~ubuntu-branches/ubuntu/oneiric/collectd/oneiric

« back to all changes in this revision

Viewing changes to src/tail.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Harl
  • Date: 2008-06-17 10:35:51 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080617103551-9d0ym3zejc7agtt3
Tags: 4.4.1-1
* New upstream release.
  - Fixed another issue of the sensors plugin affecting some chip types
    (Closes: #468143).
  - Fixed creation of "vserver" graphs in collection.cgi (Closes: #475120).
  - Fixed a segfault when using libperl 5.10.
  - collectd now ships libiptc itself.
  New plugins:
  - Ascent server statistics: ascent
  - IPMI sensors information: ipmi
  - PowerDNS name server statistics: powerdns
  - incremental parsing of logfiles: tail
  - TeamSpeak2 server statistics: teamspeak2
  - detailed virtual memory statistics: vmem
* Disable "tcpconns" plugin by default (Closes: #478759).
* Reenabled iptables plugin on all architectures (Closes: #473435).
  - Added the plugin to collectd.conf.
  - Added /usr/share/doc/collectd/examples/iptables/.
  - Added build dependency on linux-libc-dev (>= 2.6.25-4) - that version is
    required because of #479899.
* New debconf template translations:
  - gl.po, thanks to Jacobo Tarrio (Closes: #482667).
* Added a work around for #474087 (broken openipmi .pc files) by forcing the
  inclusion of the ipmi plugin and manually specifying the dependencies.
* Updated standards-version to 3.8.0 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * collectd - src/tail.c
 
3
 * Copyright (C) 2008  Florian octo Forster
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify it
 
6
 * under the terms of the GNU General Public License as published by the
 
7
 * Free Software Foundation; only version 2 of the License is applicable.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful, but
 
10
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License along
 
15
 * with this program; if not, write to the Free Software Foundation, Inc.,
 
16
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 
17
 *
 
18
 * Authors:
 
19
 *   Florian octo Forster <octo at verplant.org>
 
20
 **/
 
21
 
 
22
#include "collectd.h"
 
23
#include "common.h"
 
24
#include "plugin.h"
 
25
#include "utils_tail_match.h"
 
26
 
 
27
/*
 
28
 *  <Plugin tail>
 
29
 *    <File "/var/log/exim4/mainlog">
 
30
 *      Instance "exim"
 
31
 *      <Match>
 
32
 *        Regex "S=([1-9][0-9]*)"
 
33
 *        DSType "CounterAdd"
 
34
 *        Type "ipt_bytes"
 
35
 *        Instance "total"
 
36
 *      </Match>
 
37
 *    </File>
 
38
 *  </Plugin>
 
39
 */
 
40
 
 
41
struct ctail_config_match_s
 
42
{
 
43
  char *regex;
 
44
  int flags;
 
45
  char *type;
 
46
  char *type_instance;
 
47
};
 
48
typedef struct ctail_config_match_s ctail_config_match_t;
 
49
 
 
50
cu_tail_match_t **tail_match_list = NULL;
 
51
size_t tail_match_list_num = 0;
 
52
 
 
53
static int ctail_config_add_string (const char *name, char **dest, oconfig_item_t *ci)
 
54
{
 
55
  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
 
56
  {
 
57
    WARNING ("tail plugin: `%s' needs exactly one string argument.", name);
 
58
    return (-1);
 
59
  }
 
60
 
 
61
  sfree (*dest);
 
62
  *dest = strdup (ci->values[0].value.string);
 
63
  if (*dest == NULL)
 
64
    return (-1);
 
65
 
 
66
  return (0);
 
67
} /* int ctail_config_add_string */
 
68
 
 
69
static int ctail_config_add_match_dstype (ctail_config_match_t *cm,
 
70
    oconfig_item_t *ci)
 
71
{
 
72
  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
 
73
  {
 
74
    WARNING ("tail plugin: `DSType' needs exactly one string argument.");
 
75
    return (-1);
 
76
  }
 
77
 
 
78
  if (strncasecmp ("Gauge", ci->values[0].value.string, strlen ("Gauge")) == 0)
 
79
  {
 
80
    cm->flags = UTILS_MATCH_DS_TYPE_GAUGE;
 
81
    if (strcasecmp ("GaugeAverage", ci->values[0].value.string) == 0)
 
82
      cm->flags |= UTILS_MATCH_CF_GAUGE_AVERAGE;
 
83
    else if (strcasecmp ("GaugeMin", ci->values[0].value.string) == 0)
 
84
      cm->flags |= UTILS_MATCH_CF_GAUGE_MIN;
 
85
    else if (strcasecmp ("GaugeMax", ci->values[0].value.string) == 0)
 
86
      cm->flags |= UTILS_MATCH_CF_GAUGE_MAX;
 
87
    else if (strcasecmp ("GaugeLast", ci->values[0].value.string) == 0)
 
88
      cm->flags |= UTILS_MATCH_CF_GAUGE_LAST;
 
89
    else
 
90
      cm->flags = 0;
 
91
  }
 
92
  else if (strncasecmp ("Counter", ci->values[0].value.string, strlen ("Counter")) == 0)
 
93
  {
 
94
    cm->flags = UTILS_MATCH_DS_TYPE_COUNTER;
 
95
    if (strcasecmp ("CounterSet", ci->values[0].value.string) == 0)
 
96
      cm->flags |= UTILS_MATCH_CF_COUNTER_SET;
 
97
    else if (strcasecmp ("CounterAdd", ci->values[0].value.string) == 0)
 
98
      cm->flags |= UTILS_MATCH_CF_COUNTER_ADD;
 
99
    else if (strcasecmp ("CounterInc", ci->values[0].value.string) == 0)
 
100
      cm->flags |= UTILS_MATCH_CF_COUNTER_INC;
 
101
    else
 
102
      cm->flags = 0;
 
103
  }
 
104
  else
 
105
  {
 
106
    cm->flags = 0;
 
107
  }
 
108
 
 
109
  if (cm->flags == 0)
 
110
  {
 
111
    WARNING ("tail plugin: `%s' is not a valid argument to `DSType'.",
 
112
        ci->values[0].value.string);
 
113
    return (-1);
 
114
  }
 
115
 
 
116
  return (0);
 
117
} /* int ctail_config_add_match_dstype */
 
118
 
 
119
static int ctail_config_add_match (cu_tail_match_t *tm,
 
120
    const char *plugin_instance, oconfig_item_t *ci)
 
121
{
 
122
  ctail_config_match_t cm;
 
123
  int status;
 
124
  int i;
 
125
 
 
126
  memset (&cm, '\0', sizeof (cm));
 
127
 
 
128
  if (ci->values_num != 0)
 
129
  {
 
130
    WARNING ("tail plugin: Ignoring arguments for the `Match' block.");
 
131
  }
 
132
 
 
133
  status = 0;
 
134
  for (i = 0; i < ci->children_num; i++)
 
135
  {
 
136
    oconfig_item_t *option = ci->children + i;
 
137
 
 
138
    if (strcasecmp ("Regex", option->key) == 0)
 
139
      status = ctail_config_add_string ("Regex", &cm.regex, option);
 
140
    else if (strcasecmp ("DSType", option->key) == 0)
 
141
      status = ctail_config_add_match_dstype (&cm, option);
 
142
    else if (strcasecmp ("Type", option->key) == 0)
 
143
      status = ctail_config_add_string ("Type", &cm.type, option);
 
144
    else if (strcasecmp ("Instance", option->key) == 0)
 
145
      status = ctail_config_add_string ("Instance", &cm.type_instance, option);
 
146
    else
 
147
    {
 
148
      WARNING ("tail plugin: Option `%s' not allowed here.", option->key);
 
149
      status = -1;
 
150
    }
 
151
 
 
152
    if (status != 0)
 
153
      break;
 
154
  } /* for (i = 0; i < ci->children_num; i++) */
 
155
 
 
156
  while (status == 0)
 
157
  {
 
158
    if (cm.regex == NULL)
 
159
    {
 
160
      WARNING ("tail plugin: `Regex' missing in `Match' block.");
 
161
      status = -1;
 
162
      break;
 
163
    }
 
164
 
 
165
    if (cm.type == NULL)
 
166
    {
 
167
      WARNING ("tail plugin: `Type' missing in `Match' block.");
 
168
      status = -1;
 
169
      break;
 
170
    }
 
171
 
 
172
    if (cm.flags == 0)
 
173
    {
 
174
      WARNING ("tail plugin: `DSType' missing in `Match' block.");
 
175
      status = -1;
 
176
      break;
 
177
    }
 
178
 
 
179
    break;
 
180
  } /* while (status == 0) */
 
181
 
 
182
  if (status == 0)
 
183
  {
 
184
    status = tail_match_add_match_simple (tm, cm.regex, cm.flags,
 
185
        "tail", plugin_instance, cm.type, cm.type_instance);
 
186
 
 
187
    if (status != 0)
 
188
    {
 
189
      ERROR ("tail plugin: tail_match_add_match_simple failed.");
 
190
    }
 
191
  }
 
192
 
 
193
  sfree (cm.regex);
 
194
  sfree (cm.type);
 
195
  sfree (cm.type_instance);
 
196
 
 
197
  return (status);
 
198
} /* int ctail_config_add_match */
 
199
 
 
200
static int ctail_config_add_file (oconfig_item_t *ci)
 
201
{
 
202
  cu_tail_match_t *tm;
 
203
  char *plugin_instance = NULL;
 
204
  int num_matches = 0;
 
205
  int status;
 
206
  int i;
 
207
 
 
208
  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
 
209
  {
 
210
    WARNING ("tail plugin: `File' needs exactly one string argument.");
 
211
    return (-1);
 
212
  }
 
213
 
 
214
  tm = tail_match_create (ci->values[0].value.string);
 
215
  if (tm == NULL)
 
216
  {
 
217
    ERROR ("tail plugin: tail_match_create (%s) failed.",
 
218
        ci->values[0].value.string);
 
219
    return (-1);
 
220
  }
 
221
 
 
222
  status = 0;
 
223
  for (i = 0; i < ci->children_num; i++)
 
224
  {
 
225
    oconfig_item_t *option = ci->children + i;
 
226
 
 
227
    if (strcasecmp ("Match", option->key) == 0)
 
228
    {
 
229
      status = ctail_config_add_match (tm, plugin_instance, option);
 
230
      if (status == 0)
 
231
        num_matches++;
 
232
      /* Be mild with failed matches.. */
 
233
      status = 0;
 
234
    }
 
235
    else if (strcasecmp ("Instance", option->key) == 0)
 
236
      status = ctail_config_add_string ("Instance", &plugin_instance, option);
 
237
    else
 
238
    {
 
239
      WARNING ("tail plugin: Option `%s' not allowed here.", option->key);
 
240
      status = -1;
 
241
    }
 
242
 
 
243
    if (status != 0)
 
244
      break;
 
245
  } /* for (i = 0; i < ci->children_num; i++) */
 
246
 
 
247
  if (num_matches == 0)
 
248
  {
 
249
    ERROR ("tail plugin: No (valid) matches found for file `%s'.",
 
250
        ci->values[0].value.string);
 
251
    tail_match_destroy (tm);
 
252
    return (-1);
 
253
  }
 
254
  else
 
255
  {
 
256
    cu_tail_match_t **temp;
 
257
 
 
258
    temp = (cu_tail_match_t **) realloc (tail_match_list,
 
259
        sizeof (cu_tail_match_t *) * (tail_match_list_num + 1));
 
260
    if (temp == NULL)
 
261
    {
 
262
      ERROR ("tail plugin: realloc failed.");
 
263
      tail_match_destroy (tm);
 
264
      return (-1);
 
265
    }
 
266
 
 
267
    tail_match_list = temp;
 
268
    tail_match_list[tail_match_list_num] = tm;
 
269
    tail_match_list_num++;
 
270
  }
 
271
 
 
272
  return (0);
 
273
} /* int ctail_config_add_file */
 
274
 
 
275
static int ctail_config (oconfig_item_t *ci)
 
276
{
 
277
  int i;
 
278
 
 
279
  for (i = 0; i < ci->children_num; i++)
 
280
  {
 
281
    oconfig_item_t *option = ci->children + i;
 
282
 
 
283
    if (strcasecmp ("File", option->key) == 0)
 
284
      ctail_config_add_file (option);
 
285
    else
 
286
    {
 
287
      WARNING ("tail plugin: Option `%s' not allowed here.", option->key);
 
288
    }
 
289
  } /* for (i = 0; i < ci->children_num; i++) */
 
290
 
 
291
  return (0);
 
292
} /* int ctail_config */
 
293
 
 
294
static int ctail_init (void)
 
295
{
 
296
  if (tail_match_list_num == 0)
 
297
  {
 
298
    WARNING ("tail plugin: File list is empty. Returning an error.");
 
299
    return (-1);
 
300
  }
 
301
 
 
302
  return (0);
 
303
} /* int ctail_init */
 
304
 
 
305
static int ctail_read (void)
 
306
{
 
307
  int success = 0;
 
308
  int i;
 
309
 
 
310
  for (i = 0; i < tail_match_list_num; i++)
 
311
  {
 
312
    int status;
 
313
 
 
314
    status = tail_match_read (tail_match_list[i]);
 
315
    if (status != 0)
 
316
    {
 
317
      ERROR ("tail plugin: tail_match_read[%i] failed.", i);
 
318
    }
 
319
    else
 
320
    {
 
321
      success++;
 
322
    }
 
323
  }
 
324
 
 
325
  if (success == 0)
 
326
    return (-1);
 
327
  return (0);
 
328
} /* int ctail_read */
 
329
 
 
330
static int ctail_shutdown (void)
 
331
{
 
332
  int i;
 
333
 
 
334
  for (i = 0; i < tail_match_list_num; i++)
 
335
  {
 
336
    tail_match_destroy (tail_match_list[i]);
 
337
    tail_match_list[i] = NULL;
 
338
  }
 
339
  sfree (tail_match_list);
 
340
  tail_match_list_num = 0;
 
341
 
 
342
  return (0);
 
343
} /* int ctail_shutdown */
 
344
 
 
345
void module_register (void)
 
346
{
 
347
  plugin_register_complex_config ("tail", ctail_config);
 
348
  plugin_register_init ("tail", ctail_init);
 
349
  plugin_register_read ("tail", ctail_read);
 
350
  plugin_register_shutdown ("tail", ctail_shutdown);
 
351
} /* void module_register */
 
352
 
 
353
/* vim: set sw=2 sts=2 ts=8 : */