src/data_provider.c: Call lcc_flush() before querying the data.
[collection4.git] / src / data_provider.c
1 /**
2  * collection4 - data_provider.c
3  * Copyright (C) 2010  Florian octo Forster
4  * Copyright (C) 2011  noris network AG
5  * 
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  * 
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  * 
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA  02110-1301  USA
20  *
21  * Authors:
22  *   Florian octo Forster <ff at octo.it>
23  **/
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <assert.h>
29
30 #include "data_provider.h"
31 #include "dp_rrdtool.h"
32 #include "graph_ident.h"
33
34 #include <fcgiapp.h>
35 #include <fcgi_stdio.h>
36
37 #include <collectd/client.h>
38
39 /* TODO: Turn this into an array for multiple data providers. */
40 static data_provider_t *data_provider = NULL;
41
42 static lcc_connection_t *collectd_connection = NULL;
43
44 static int data_provider_ident_flush (const graph_ident_t *ident) /* {{{ */
45 {
46   char *ident_str;
47   lcc_identifier_t ident_lcc;
48   int status;
49
50   if (ident == NULL)
51     return (EINVAL);
52
53   ident_str = ident_to_string (ident);
54   if (ident_str == NULL)
55     return (ENOMEM);
56
57   if (collectd_connection == NULL)
58   {
59     /* TODO: Make socket path configurable */
60     status = lcc_connect (/* path = */ "/var/run/collectd-unixsock",
61                     &collectd_connection);
62     if (status != 0)
63     {
64       assert (collectd_connection == NULL);
65       fprintf (stderr, "data_provider_ident_flush: lcc_connect failed "
66           "with status %i.\n", status);
67       return (status);
68     }
69     assert (collectd_connection != NULL);
70   }
71
72   memset (&ident_lcc, 0, sizeof (ident_lcc));
73   status = lcc_string_to_identifier (collectd_connection,
74       &ident_lcc, ident_str);
75   if (status != 0)
76   {
77     fprintf (stderr, "data_provider_ident_flush: lcc_string_to_identifier "
78         "failed: %s (%i)\n",
79         lcc_strerror (collectd_connection), status);
80     free (ident_str);
81     return (status);
82   }
83
84   status = lcc_flush (collectd_connection,
85       /* write-plugin = */ NULL,
86       /* identifier   = */ &ident_lcc,
87       /* timeout      = */ -1);
88   if (status != 0)
89   {
90     fprintf (stderr, "data_provider_ident_flush: lcc_flush (\"%s\") failed: %s (%i)\n",
91         ident_str, lcc_strerror (collectd_connection), status);
92     free (ident_str);
93
94     lcc_disconnect (collectd_connection);
95     collectd_connection = NULL;
96
97     return (status);
98   }
99
100   /* fprintf (stderr, "data_provider_ident_flush: lcc_flush (\"%s\") succeeded.\n", ident_str); */
101   free (ident_str);
102   return (0);
103 } /* }}} int data_provider_ident_flush */
104
105 int data_provider_config (const oconfig_item_t *ci) /* {{{ */
106 {
107   /* FIXME: Actually determine which data provider to call. */
108   return (dp_rrdtool_config (ci));
109 } /* }}} int data_provider_config */
110
111 int data_provider_register (const char *name, data_provider_t *p) /* {{{ */
112 {
113   fprintf (stderr, "data_provider_register (name = %s, ptr = %p)\n",
114       name, (void *) p);
115
116   if (data_provider == NULL)
117     data_provider = malloc (sizeof (*data_provider));
118   if (data_provider == NULL)
119     return (ENOMEM);
120
121   *data_provider = *p;
122
123   return (0);
124 } /* }}} int data_provider_register */
125
126 int data_provider_get_idents (dp_get_idents_callback callback, /* {{{ */
127     void *user_data)
128 {
129   int status;
130
131   if (data_provider == NULL)
132     return (EINVAL);
133
134   /* TODO: Iterate over all data providers */
135   status = data_provider->get_idents (data_provider->private_data,
136       callback, user_data);
137
138   return (status);
139 } /* }}} int data_provider_get_idents */
140
141 int data_provider_get_ident_ds_names (graph_ident_t *ident, /* {{{ */
142     dp_list_get_ident_ds_names_callback callback, void *user_data)
143 {
144   if (data_provider == NULL)
145     return (EINVAL);
146
147   return (data_provider->get_ident_ds_names (data_provider->private_data,
148         ident, callback, user_data));
149 } /* }}} int data_provider_get_ident_ds_names */
150
151 int data_provider_get_ident_data (graph_ident_t *ident, /* {{{ */
152     const char *ds_name,
153     dp_time_t begin, dp_time_t end,
154     dp_get_ident_data_callback callback, void *user_data)
155 {
156   if (data_provider == NULL)
157     return (EINVAL);
158
159   data_provider_ident_flush (ident);
160
161   return (data_provider->get_ident_data (data_provider->private_data,
162         ident, ds_name, begin, end, callback, user_data));
163 } /* }}} int data_provider_get_ident_data */
164
165 /* vim: set sw=2 sts=2 et fdm=marker : */