allow multiple lines to define processes for the same process group; allow the user to override the "other" group
Costa Tsaousis (ktsaou) committed
Dec 25, 2016 at 23:49 UTC
356b7f4a00052ca24a34e98f7f1e6c29a2ceed04
1 file changed
+54
-40
src/apps_plugin.c
+54
-40
@@ -189,10 +189,11 @@ struct target *get_groups_target(gid_t gid)
189
190
// find or create a new target
191
// there are targets that are just aggregated to other target (the second argument)
192
-struct target *get_apps_groups_target(const char *id, struct target *target) {
193
- int tdebug = 0, thidden = 0, ends_with = 0;
192
+struct target *get_apps_groups_target(const char *id, struct target *target, const char *name) {
193
+ int tdebug = 0, thidden = target?target->hidden:0, ends_with = 0;
194
const char *nid = id;
195
196
+ // extract the options
197
while(nid[0] == '-' || nid[0] == '+' || nid[0] == '*') {
198
if(nid[0] == '-') thidden = 1;
199
if(nid[0] == '+') tdebug = 1;
@@ -201,6 +202,7 @@ struct target *get_apps_groups_target(const char *id, struct target *target) {
202
}
203
uint32_t hash = simple_hash(id);
204
205
+ // find if it already exists
206
struct target *w, *last = apps_groups_root_target;
207
for(w = apps_groups_root_target ; w ; w = w->next) {
208
if(w->idhash == hash && strncmp(nid, w->id, MAX_NAME) == 0)
@@ -209,11 +211,37 @@ struct target *get_apps_groups_target(const char *id, struct target *target) {
211
last = w;
212
}
213
214
+ // find an existing target
215
+ if(unlikely(!target)) {
216
+ while(*name == '-') {
217
+ if(*name == '-') thidden = 1;
218
+ name++;
219
+ }
220
+ for(target = apps_groups_root_target ; target ; target = target->next) {
221
+ if(!target->target && strcmp(name, target->name) == 0)
222
+ break;
223
+ }
224
+ if(unlikely(debug)) {
225
+ if(unlikely(target))
226
+ fprintf(stderr, "apps.plugin: REUSING TARGET NAME '%s' on ID '%s'\n", target->name, target->id);
227
+ else
228
+ fprintf(stderr, "apps.plugin: NEW TARGET NAME '%s' on ID '%s'\n", name, id);
229
+ }
230
+ }
231
+
232
+ if(target && target->target)
233
+ fatal("Internal Error: request to link process '%s' to target '%s' which is linked to target '%s'", id, target->id, target->target->id);
234
+
235
w = callocz(sizeof(struct target), 1);
236
strncpyz(w->id, nid, MAX_NAME);
237
w->idhash = simple_hash(w->id);
238
216
- strncpyz(w->name, nid, MAX_NAME);
239
+ if(unlikely(!target))
240
+ // copy the name
241
+ strncpyz(w->name, name, MAX_NAME);
242
+ else
243
+ // copy the id
244
+ strncpyz(w->name, nid, MAX_NAME);
245
246
strncpyz(w->compare, nid, MAX_COMPARE_NAME);
247
size_t len = strlen(w->compare);
@@ -241,7 +269,7 @@ struct target *get_apps_groups_target(const char *id, struct target *target) {
269
fprintf(stderr, "apps.plugin: ADDING TARGET ID '%s', process name '%s' (%s), aggregated on target '%s', options: %s %s\n"
270
, w->id
271
, w->compare, (w->starts_with && w->ends_with)?"substring":((w->starts_with)?"prefix":((w->ends_with)?"suffix":"exact"))
244
- , w->target?w->target->id:w->id
272
+ , w->target?w->target->name:w->name
273
, (w->hidden)?"hidden":"-"
274
, (w->debug)?"debug":"-"
275
);
@@ -250,11 +278,11 @@ struct target *get_apps_groups_target(const char *id, struct target *target) {
278
}
279
280
// read the apps_groups.conf file
253
-int read_apps_groups_conf(const char *name)
281
+int read_apps_groups_conf(const char *file)
282
{
283
char filename[FILENAME_MAX + 1];
284
257
- snprintfz(filename, FILENAME_MAX, "%s/apps_%s.conf", config_dir, name);
285
+ snprintfz(filename, FILENAME_MAX, "%s/apps_%s.conf", config_dir, file);
286
287
if(unlikely(debug))
288
fprintf(stderr, "apps.plugin: process groups file: '%s'\n", filename);
@@ -274,59 +302,45 @@ int read_apps_groups_conf(const char *name)
302
303
for(line = 0; line < lines ;line++) {
304
unsigned long word, words = procfile_linewords(ff, line);
277
- struct target *w = NULL;
305
+ if(!words) continue;
306
+
307
+ char *name = procfile_lineword(ff, line, 0);
308
+ if(!name || !*name) continue;
309
279
- char *t = procfile_lineword(ff, line, 0);
280
- if(!t || !*t) continue;
310
+ // find a possibly existing target
311
+ struct target *w = NULL;
312
313
+ // loop through all words, skipping the first one (the name)
314
for(word = 0; word < words ;word++) {
315
char *s = procfile_lineword(ff, line, word);
316
if(!s || !*s) continue;
317
if(*s == '#') break;
318
287
- if(t == s) continue;
319
+ // is this the first word? skip it
320
+ if(s == name) continue;
321
289
- struct target *n = get_apps_groups_target(s, w);
322
+ // add this target
323
+ struct target *n = get_apps_groups_target(s, w, name);
324
if(!n) {
325
error("Cannot create target '%s' (line %lu, word %lu)", s, line, word);
326
continue;
327
}
328
295
- if(!w) w = n;
296
- }
297
-
298
- if(w) {
299
- int tdebug = 0, thidden = 0;
300
-
301
- while(t[0] == '-' || t[0] == '+') {
302
- if(t[0] == '-') thidden = 1;
303
- if(t[0] == '+') tdebug = 1;
304
- t++;
305
- }
306
-
307
- strncpyz(w->name, t, MAX_NAME);
308
- w->hidden = thidden;
309
- w->debug = tdebug;
310
-
311
- if(unlikely(debug))
312
- fprintf(stderr, "apps.plugin: AGGREGATION TARGET NAME '%s' on ID '%s', process name '%s' (%s), aggregated on target '%s', options: %s %s\n"
313
- , w->name
314
- , w->id
315
- , w->compare, (w->starts_with && w->ends_with)?"substring":((w->starts_with)?"prefix":((w->ends_with)?"suffix":"exact"))
316
- , w->target?w->target->id:w->id
317
- , (w->hidden)?"hidden":"-"
318
- , (w->debug)?"debug":"-"
319
- );
329
+ // just some optimization
330
+ // to avoid searching for a target for each process
331
+ if(!w) w = n->target?n->target:n;
332
}
333
}
334
335
procfile_close(ff);
336
325
- apps_groups_default_target = get_apps_groups_target("p+!o@w#e$i^r&7*5(-i)l-o_", NULL); // match nothing
337
+ apps_groups_default_target = get_apps_groups_target("p+!o@w#e$i^r&7*5(-i)l-o_", NULL, "other"); // match nothing
338
if(!apps_groups_default_target)
327
- error("Cannot create default target");
328
- else
329
- strncpyz(apps_groups_default_target->name, "other", MAX_NAME);
339
+ fatal("Cannot create default target");
340
+
341
+ // allow the user to override group 'other'
342
+ if(apps_groups_default_target->target)
343
+ apps_groups_default_target = apps_groups_default_target->target;
344
345
return 0;
346
}