@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class PhabricatorLockLogManagementWorkflow
4 extends PhabricatorLockManagementWorkflow {
5
6 protected function didConstruct() {
7 $this
8 ->setName('log')
9 ->setSynopsis(pht('Enable, disable, or show the lock log.'))
10 ->setArguments(
11 array(
12 array(
13 'name' => 'enable',
14 'help' => pht('Enable the lock log.'),
15 ),
16 array(
17 'name' => 'disable',
18 'help' => pht('Disable the lock log.'),
19 ),
20 array(
21 'name' => 'name',
22 'param' => 'name',
23 'help' => pht('Review logs for a specific lock.'),
24 ),
25 ));
26 }
27
28 public function execute(PhutilArgumentParser $args) {
29 $is_enable = $args->getArg('enable');
30 $is_disable = $args->getArg('disable');
31
32 if ($is_enable && $is_disable) {
33 throw new PhutilArgumentUsageException(
34 pht(
35 'You can not both "--enable" and "--disable" the lock log.'));
36 }
37
38 $with_name = $args->getArg('name');
39
40 if ($is_enable || $is_disable) {
41 if (phutil_nonempty_string($with_name)) {
42 throw new PhutilArgumentUsageException(
43 pht(
44 'You can not both "--enable" or "--disable" with search '.
45 'parameters like "--name".'));
46 }
47
48 $gc = new PhabricatorDaemonLockLogGarbageCollector();
49 $is_enabled = (bool)$gc->getRetentionPolicy();
50
51 $config_key = 'phd.garbage-collection';
52 $const = $gc->getCollectorConstant();
53 $value = PhabricatorEnv::getEnvConfig($config_key);
54
55 if ($is_disable) {
56 if (!$is_enabled) {
57 echo tsprintf(
58 "%s\n",
59 pht('Lock log is already disabled.'));
60 return 0;
61 }
62 echo tsprintf(
63 "%s\n",
64 pht('Disabling the lock log.'));
65
66 unset($value[$const]);
67 } else {
68 if ($is_enabled) {
69 echo tsprintf(
70 "%s\n",
71 pht('Lock log is already enabled.'));
72 return 0;
73 }
74 echo tsprintf(
75 "%s\n",
76 pht('Enabling the lock log.'));
77
78 $value[$const] = phutil_units('24 hours in seconds');
79 }
80
81 id(new PhabricatorConfigLocalSource())
82 ->setKeys(
83 array(
84 $config_key => $value,
85 ));
86
87 echo tsprintf(
88 "%s\n",
89 pht('Done.'));
90
91 echo tsprintf(
92 "%s\n",
93 pht('Restart daemons to apply changes.'));
94
95 return 0;
96 }
97
98 $table = new PhabricatorDaemonLockLog();
99 $conn = $table->establishConnection('r');
100
101 $parts = array();
102 if (phutil_nonempty_string($with_name)) {
103 $parts[] = qsprintf(
104 $conn,
105 'lockName = %s',
106 $with_name);
107 }
108
109 if (!$parts) {
110 $constraint = qsprintf($conn, '1 = 1');
111 } else {
112 $constraint = qsprintf($conn, '%LA', $parts);
113 }
114
115 $logs = $table->loadAllWhere(
116 '%Q ORDER BY id DESC LIMIT 100',
117 $constraint);
118 $logs = array_reverse($logs);
119
120 if (!$logs) {
121 echo tsprintf(
122 "%s\n",
123 pht('No matching lock logs.'));
124 return 0;
125 }
126
127 $table = id(new PhutilConsoleTable())
128 ->setBorders(true)
129 ->addColumn(
130 'id',
131 array(
132 'title' => pht('Lock'),
133 ))
134 ->addColumn(
135 'name',
136 array(
137 'title' => pht('Name'),
138 ))
139 ->addColumn(
140 'acquired',
141 array(
142 'title' => pht('Acquired'),
143 ))
144 ->addColumn(
145 'released',
146 array(
147 'title' => pht('Released'),
148 ))
149 ->addColumn(
150 'held',
151 array(
152 'title' => pht('Held'),
153 ))
154 ->addColumn(
155 'parameters',
156 array(
157 'title' => pht('Parameters'),
158 ))
159 ->addColumn(
160 'context',
161 array(
162 'title' => pht('Context'),
163 ));
164
165 $viewer = $this->getViewer();
166
167 foreach ($logs as $log) {
168 $created = $log->getDateCreated();
169 $released = $log->getLockReleased();
170
171 if ($released) {
172 $held = '+'.($released - $created);
173 } else {
174 $held = null;
175 }
176
177 $created = phabricator_datetime($created, $viewer);
178 $released = phabricator_datetime($released, $viewer);
179
180 $parameters = $log->getLockParameters();
181 $context = $log->getLockContext();
182
183 $table->addRow(
184 array(
185 'id' => $log->getID(),
186 'name' => $log->getLockName(),
187 'acquired' => $created,
188 'released' => $released,
189 'held' => $held,
190 'parameters' => $this->flattenParameters($parameters),
191 'context' => $this->flattenParameters($context),
192 ));
193 }
194
195 $table->draw();
196
197 return 0;
198 }
199
200 private function flattenParameters(array $params, $keys = true) {
201 $flat = array();
202 foreach ($params as $key => $value) {
203 if (is_array($value)) {
204 $value = $this->flattenParameters($value, false);
205 }
206 if ($keys) {
207 $flat[] = "{$key}={$value}";
208 } else {
209 $flat[] = "{$value}";
210 }
211 }
212
213 if ($keys) {
214 $flat = implode(', ', $flat);
215 } else {
216 $flat = implode(' ', $flat);
217 }
218
219 return $flat;
220 }
221
222}