Skip to content

Commit 81833f1

Browse files
committed
Version 0.9.67
- Added custom job labels.
1 parent 4fa8743 commit 81833f1

File tree

7 files changed

+61
-38
lines changed

7 files changed

+61
-38
lines changed

docs/Plugins.md

+42-25
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
- [Custom Data Tables](#custom-data-tables)
1818
- [Custom HTML Content](#custom-html-content)
1919
- [Updating The Event](#updating-the-event)
20+
- [Custom Job Labels](#custom-job-labels)
2021
+ [Job Environment Variables](#job-environment-variables)
2122
* [Sample Node Plugin](#sample-node-plugin)
2223
* [Sample Perl Plugin](#sample-perl-plugin)
@@ -47,7 +48,7 @@ The location of the `node` binary may vary on your servers.
4748

4849
As soon as your Plugin is launched as a sub-process, a JSON document is piped to its STDIN stream, describing the job. This will be compacted onto a single line followed by an EOL, so you can simply read a line, and not have to worry about locating the start and end of the JSON. Here is an example JSON document (pretty-printed here for display purposes):
4950

50-
```js
51+
```json
5152
{
5253
"id": "jihuxvagi01",
5354
"hostname": "joeretina.local",
@@ -84,13 +85,13 @@ The `params` object will contain all the custom parameter keys defined when you
8485

8586
Your Plugin is expected to write JSON to STDOUT in order to report status back to the Cronicle daemon. At the very least, you need to notify Cronicle that the job was completed, and the result of the job (i.e. success or fail). This is done by printing a JSON object with a `complete` property set to `1`, and a `code` property set to `0` indicating success. You need to make sure the JSON is compacted onto a single line, and ends with a single EOL character (`\n` on Unix). Example:
8687

87-
```js
88+
```json
8889
{ "complete": 1, "code": 0 }
8990
```
9091

9192
This tells Cronicle that the job was completed successfully, and your process is about to exit. However, if the job failed and you need to report an error, you need to set the `code` property set to any non-zero error code you want, and add a `description` property set to a custom error string. Include these along with the `complete` property in the JSON. Example:
9293

93-
```js
94+
```json
9495
{ "complete": 1, "code": 999, "description": "Failed to connect to database." }
9596
```
9697

@@ -104,7 +105,7 @@ Please note that the once you send a JSON line containing the `complete` flag, C
104105

105106
In addition to reporting success or failure at the end of a job, you can also optionally report progress at custom intervals while your job is running. This is how Cronicle can display its visual progress meter in the UI, as well as calculate the estimated time remaining. To update the progress of a job, simply print a JSON document with a `progress` property, set to a number between `0.0` and `1.0`. Example:
106107

107-
```js
108+
```json
108109
{ "progress": 0.5 }
109110
```
110111

@@ -114,23 +115,23 @@ This would show progress at 50% completion, and automatically calculate the esti
114115

115116
You can optionally include performance metrics at the end of a job, which are displayed as a pie chart on the [Job Details Tab](WebUI.md#job-details-tab). These metrics can consist of any categories you like, and the JSON format is a simple `perf` object where the values represent the amount of time spent in seconds. Example:
116117

117-
```js
118+
```json
118119
{ "perf": { "db": 18.51, "http": 3.22, "gzip": 0.84 } }
119120
```
120121

121122
The perf keys can be anything you want. They are just arbitrary categories you can make up, which represent how your Plugin spent its time during the job.
122123

123124
Cronicle accepts a number of different formats for the perf metrics, to accommodate various performance tracking libraries. For example, you can provide the metrics in query string format, like this:
124125

125-
```js
126+
```json
126127
{ "perf": "db=18.51&http=3.22&gzip=0.84" }
127128
```
128129

129130
If your metrics include a `total` (or `t`) in addition to other metrics, this is assumed to represent the total time, and will automatically be excluded from the pie chart (but included in the performance history graph).
130131

131132
If you track metrics in units other than seconds, you can provide the `scale`. For example, if your metrics are all in milliseconds, just set the `scale` property to `1000`. Example:
132133

133-
```js
134+
```json
134135
{ "perf": { "scale": 1000, "db": 1851, "http": 3220, "gzip": 840 } }
135136
```
136137

@@ -140,15 +141,15 @@ The slightly more complex format produced by our own [pixl-perf](https://www.npm
140141

141142
In order for the pie chart to be accurate, your perf metrics must not overlap each other. Each metric should represent a separate period of time. Put another way, if all the metrics were added together, they should equal the total time. To illustrate this point, consider the following "bad" example:
142143

143-
```js
144+
```json
144145
{ "perf": { "database": 18.51, "run_sql_query": 3.22, "connect_to_db": 0.84 } }
145146
```
146147

147148
In this case the Plugin is tracking three different metrics, but the `database` metric encompasses *all* database related activities, including the `run_sql_query` and `connect_to_db`. So the `database` metric overlaps the others. Cronicle has no way of knowing this, so the pie chart would be quite inaccurate, because the three metrics do not add up to the total time.
148149

149150
However, if you want to track nested metrics as well as a parent metric, just make sure you prefix your perf keys properly. In the above example, all you would need to do is rename the keys like this:
150151

151-
```js
152+
```json
152153
{ "perf": { "db": 18.51, "db_run_sql": 3.22, "db_connect": 0.84 } }
153154
```
154155

@@ -162,25 +163,25 @@ Notification settings for the job are configured in the UI at the event level, a
162163

163164
For example, if you only want to send a successful e-mail in certain cases, and want to disable it based on some outcome from inside the Plugin, just print some JSON to STDOUT like this:
164165

165-
```js
166+
```json
166167
{ "notify_success": "" }
167168
```
168169

169170
This will disable the e-mail that is normally sent upon success. Similarly, if you want to disable the failure e-mail, print this to STDOUT:
170171

171-
```js
172+
```json
172173
{ "notify_fail": "" }
173174
```
174175

175176
Another potential use of this feature is to change who gets e-mailed, based on a decision made inside your Plugin. For example, you may have multiple error severity levels, and want to e-mail a different set of people for the really severe ones. To do that, just specify a new set of e-mail addresses in the `notify_fail` property:
176177

177-
```js
178+
```json
178179
{ "notify_fail": "[email protected]" }
179180
```
180181

181182
These JSON updates can be sent as standalone records as shown here, at any time during your job run, or you can batch everything together at the very end:
182183

183-
```js
184+
```json
184185
{ "complete": 1, "code": 999, "description": "Failed to connect to database.", "perf": { "db": 18.51, "db_run_sql": 3.22, "db_connect": 0.84 }, "notify_fail": "[email protected]" }
185186
```
186187

@@ -190,21 +191,21 @@ You can enable or disable [Chain Reaction](WebUI.md#chain-reaction) mode on the
190191

191192
To enable a chain reaction, you need to know the Event ID of the event you want to trigger. You can determine this by editing the event in the UI and copy the Event ID from the top of the form, just above the title. Then you can specify the ID in your jobs by printing some JSON to STDOUT like this:
192193

193-
```js
194+
```json
194195
{ "chain": "e29bf12db" }
195196
```
196197

197198
Remember that your job must complete successfully in order to trigger the chain reaction, and fire off the next event. However, if you want to run a event only on job failure, set the `chain_error` property instead:
198199

199-
```js
200+
```json
200201
{ "chain_error": "e29bf12db" }
201202
```
202203

203204
You set both the `chain` and `chain_error` properties, to run different events on success / failure.
204205

205206
To disable chain reaction mode, set the `chain` and `chain_error` properties to false or empty strings:
206207

207-
```js
208+
```json
208209
{ "chain": "", "chain_error": "" }
209210
```
210211

@@ -221,7 +222,7 @@ When a chained event runs, some additional information is included in the initia
221222

222223
You can pass custom JSON data to the next event in the chain, when using a [Chain Reaction](WebUI.md#chain-reaction) event. Simply specify a JSON property called `chain_data` in your JSON output, and pass in anything you want (can be a complex object / array tree), and the next event will receive it. Example:
223224

224-
```js
225+
```json
225226
{ "chain": "e29bf12db", "chain_data": { "custom_key": "foobar", "value": 42 } }
226227
```
227228

@@ -231,7 +232,7 @@ So in this case when the event `e29bf12db` runs, it will be passed your `chain_d
231232

232233
In addition to passing `chain_data` to chained events (see above), you can also override some or all the *parameters* of the chained event (the key/value pairs normally populated by the Plugin). To do this, specify a JSON property called `chain_params` in your JSON output, and pass in an object containing param keys. This will be merged with the default event Plugin parameters when the chained job is executed. Example:
233234

234-
```js
235+
```json
235236
{ "chain": "e29bf12db", "chain_params": { "custom_key": "foobar", "value": 42 } }
236237
```
237238

@@ -250,7 +251,7 @@ If your Plugin produces statistics or other tabular data at the end of a run, yo
250251

251252
Here is an example data table. Note that this has been expanded for documentation purposes, but in practice your JSON needs to be compacted onto a single line when printed to STDOUT.
252253

253-
```js
254+
```json
254255
{
255256
"table": {
256257
"title": "Sample Job Stats",
@@ -290,12 +291,12 @@ If you would prefer to generate your own HTML content from your Plugin code, and
290291

291292
Here is an example HTML report. Note that this has been expanded for documentation purposes, but in practice your JSON needs to be compacted onto a single line when printed to STDOUT.
292293

293-
```js
294+
```json
294295
{
295296
"html": {
296-
title: "Sample Job Report",
297-
content: "This is <b>HTML</b> so you can use <i>styling</i> and such.",
298-
caption: "This is a caption displayed under your HTML content."
297+
"title": "Sample Job Report",
298+
"content": "This is <b>HTML</b> so you can use <i>styling</i> and such.",
299+
"caption": "This is a caption displayed under your HTML content."
299300
}
300301
}
301302
```
@@ -308,15 +309,31 @@ Your job can optionally trigger an event update when it completes. This can be
308309

309310
To update the event for a job, simply include an `update_event` object in your Plugin's JSON output, containing any properties from the [Event Data Format](APIReference.md#event-data-format). Example:
310311

311-
```js
312+
```json
312313
{
313314
"update_event": {
314315
"enabled": 0
315316
}
316317
}
317318
```
318319

319-
This would cause the event to be disabled, so the schedule would no longer launch it. Note that you can only update the event once, and it happens at the completion of your job.
320+
This would cause the event to be disabled, so the schedule would no longer launch it. Note that you can only update the event once, and it happens at the completion of your job. Remember, the JSON must be compacted on one line like this:
321+
322+
```json
323+
{ "update_event": { "enabled": 0 } }
324+
```
325+
326+
#### Custom Job Labels
327+
328+
Your can optionally add custom labels to your jobs, which will be displayed on the completed job history pages alongside the Job IDs. This is useful if you launch jobs with custom parameters, and need to differentiate them in the completed list.
329+
330+
To set the label for a job, simply include a `label` property in your Plugin's JSON output, set to any string you want. Example:
331+
332+
```json
333+
{ "label": "Reindex Database" }
334+
```
335+
336+
This would cause the "Reindex Database" label to be displayed alongside the Job ID.
320337

321338
### Job Environment Variables
322339

htdocs/js/pages/Base.class.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,11 @@ Class.subclass( Page, "Page.Base", {
5454
return( app.user && app.user.privileges && app.user.privileges.admin );
5555
},
5656

57-
getNiceJob: function(id) {
58-
if (!id) return '(None)';
59-
if (typeof(id) == 'object') id = id.id;
60-
return '<div style="white-space:nowrap;"><i class="fa fa-pie-chart">&nbsp;</i>' + id + '</div>';
57+
getNiceJob: function(job) {
58+
if (!job) return '(None)';
59+
var nice_id = job.id;
60+
if (job.label) nice_id = job.label + ' (' + job.id + ')';
61+
return '<div style="white-space:nowrap;"><i class="fa fa-pie-chart">&nbsp;</i>' + nice_id + '</div>';
6162
},
6263

6364
getNiceEvent: function(title, width) {

htdocs/js/pages/History.class.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ Class.subclass( Page.Base, "Page.History", {
105105
if (!plugin && job.plugin_title) plugin = { id: job.plugin, title: job.plugin_title };
106106

107107
var job_link = '<div class="td_big">--</div>';
108-
if (job.id) job_link = '<div class="td_big"><a href="#JobDetails?id='+job.id+'">' + self.getNiceJob('<b>' + job.id + '</b>') + '</a></div>';
108+
if (job.id) job_link = '<div class="td_big"><a href="#JobDetails?id='+job.id+'"><b>' + self.getNiceJob(job) + '</b></a></div>';
109109

110110
var tds = [
111111
job_link,
@@ -708,7 +708,7 @@ Class.subclass( Page.Base, "Page.History", {
708708
if (job.mem) mem_avg = short_float( (job.mem.total || 0) / (job.mem.count || 1) );
709709

710710
var tds = [
711-
'<div class="td_big" style="white-space:nowrap;"><a href="#JobDetails?id='+job.id+'"><i class="fa fa-pie-chart">&nbsp;</i><b>' + job.id.substring(0, 11) + '</b></span></div>',
711+
'<div class="td_big"><a href="#JobDetails?id=' + job.id + '"><b>' + self.getNiceJob(job) + '</b></a></div>',
712712
self.getNiceGroup( null, job.hostname, col_width ),
713713
(job.code == 0) ? '<span class="color_label green"><i class="fa fa-check">&nbsp;</i>Success</span>' : '<span class="color_label red"><i class="fa fa-warning">&nbsp;</i>Error</span>',
714714
get_nice_date_time( job.time_start, false, true ),

htdocs/js/pages/Home.class.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ Class.subclass( Page.Base, "Page.Home", {
349349
if (job.pending && job.log_file) {
350350
// job in retry delay
351351
tds = [
352-
'<div class="td_big"><span class="link" onMouseUp="$P().go_job_details('+idx+')">' + self.getNiceJob(job.id) + '</span></div>',
352+
'<div class="td_big"><span class="link" onMouseUp="$P().go_job_details('+idx+')">' + self.getNiceJob(job) + '</span></div>',
353353
self.getNiceEvent( job.event_title, col_width ),
354354
self.getNiceCategory( cat, col_width ),
355355
// self.getNicePlugin( plugin ),
@@ -363,7 +363,7 @@ Class.subclass( Page.Base, "Page.Home", {
363363
else if (job.pending) {
364364
// multiplex stagger delay
365365
tds = [
366-
'<div class="td_big">' + self.getNiceJob(job.id) + '</div>',
366+
'<div class="td_big">' + self.getNiceJob(job) + '</div>',
367367
self.getNiceEvent( job.event_title, col_width ),
368368
self.getNiceCategory( cat, col_width ),
369369
// self.getNicePlugin( plugin ),
@@ -377,7 +377,7 @@ Class.subclass( Page.Base, "Page.Home", {
377377
else {
378378
// active job
379379
tds = [
380-
'<div class="td_big"><span class="link" onMouseUp="$P().go_job_details('+idx+')">' + self.getNiceJob(job.id) + '</span></div>',
380+
'<div class="td_big"><span class="link" onMouseUp="$P().go_job_details('+idx+')">' + self.getNiceJob(job) + '</span></div>',
381381
self.getNiceEvent( job.event_title, col_width ),
382382
self.getNiceCategory( cat, col_width ),
383383
// self.getNicePlugin( plugin ),

htdocs/js/pages/JobDetails.class.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,12 @@ Class.subclass( Page.Base, "Page.JobDetails", {
218218
html += '<fieldset style="margin-top:8px; margin-right:0px; padding-top:10px; position:relative;"><legend>Job Details</legend>';
219219

220220
// if (event.id && !event.multiplex) html += '<div class="button mini" style="position:absolute; top:15px; left:100%; margin-left:-110px;" onMouseUp="$P().run_again()">Run Again</div>';
221+
var nice_id = job.id;
222+
if (job.label) nice_id = job.label + ' (' + job.id + ')';
221223

222224
html += '<div style="float:left; width:25%;">';
223225
html += '<div class="info_label">JOB ID</div>';
224-
html += '<div class="info_value">' + job.id + '</div>';
226+
html += '<div class="info_value">' + nice_id + '</div>';
225227

226228
html += '<div class="info_label">EVENT NAME</div>';
227229
html += '<div class="info_value">';
@@ -782,10 +784,12 @@ Class.subclass( Page.Base, "Page.JobDetails", {
782784
html += '<fieldset style="margin-top:0px; margin-right:0px; padding-top:10px; position:relative"><legend>Job Details</legend>';
783785

784786
// html += '<div class="button mini" style="position:absolute; top:15px; left:100%; margin-left:-110px;" onMouseUp="$P().abort_job()">Abort Job...</div>';
787+
var nice_id = job.id;
788+
if (job.label) nice_id = job.label + ' (' + job.id + ')';
785789

786790
html += '<div style="float:left; width:25%;">';
787791
html += '<div class="info_label">JOB ID</div>';
788-
html += '<div class="info_value">' + job.id + '</div>';
792+
html += '<div class="info_value">' + nice_id + '</div>';
789793

790794
html += '<div class="info_label">EVENT NAME</div>';
791795
html += '<div class="info_value"><a href="#Schedule?sub=edit_event&id='+job.event+'">' + this.getNiceEvent(job.event_title, col_width) + '</a></div>';

lib/job.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ module.exports = Class.create({
713713
}
714714

715715
// only pull in properties we recognize
716-
['progress', 'complete', 'code', 'description', 'perf', 'update_event', 'table', 'html', 'chain', 'chain_data', 'chain_params', 'chain_error', 'notify_success', 'notify_fail'].forEach( function(key) {
716+
['progress', 'complete', 'code', 'description', 'perf', 'update_event', 'table', 'html', 'chain', 'chain_data', 'chain_params', 'chain_error', 'notify_success', 'notify_fail', 'label'].forEach( function(key) {
717717
if (key in data) job[key] = data[key];
718718
} );
719719

@@ -1336,6 +1336,7 @@ module.exports = Class.create({
13361336
plugin_title: job.plugin_title
13371337
};
13381338
if (job.code) stub.description = job.description || 'Unknown Error';
1339+
if (job.label) stub.label = job.label;
13391340

13401341
// only store in activity log if job failed
13411342
if (job.code != 0) {

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Cronicle",
3-
"version": "0.9.66",
3+
"version": "0.9.67",
44
"description": "A simple, distributed task scheduler and runner with a web based UI.",
55
"author": "Joseph Huckaby <[email protected]>",
66
"homepage": "https://github.com/jhuckaby/Cronicle",

0 commit comments

Comments
 (0)