1 /*
2 * Copyright (c) 2002-2012 Balabit
3 * Copyright (c) 1998-2012 Balázs Scheidler
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 * As an additional exemption you are allowed to compile & link against the
20 * OpenSSL libraries as published by the OpenSSL project. See the file
21 * COPYING for details.
22 *
23 */
24
25 #ifndef DRIVER_H_INCLUDED
26 #define DRIVER_H_INCLUDED
27
28 #include "syslog-ng.h"
29 #include "logpipe.h"
30 #include "logqueue.h"
31 #include "cfg.h"
32
33 /*
34 * Drivers overview
35 * ================
36 *
37 * In syslog-ng nomenclature a driver is either responsible for handling
38 * incoming messages (also known as source driver), or to send them out to
39 * another party (also known as the destination driver). Source drivers are
40 * created in "source" statements and destination drivers are similarly
41 * created in "destination" statements.
42 *
43 * Drivers are derived from LogPipes, in essence they use the same "queue"
44 * method to forward messages further down the processing pipeline.
45 *
46 * Driver plugins
47 * ==============
48 *
49 * It is possible to change the behaviour of a driver somewhat by adding
50 * "plugins" to drivers. These plugins basically get a chance to override
51 * LogDriver virtual methods, change their semantics and possibly rely on
52 * the original behaviour too. This way, functionalities that are present
53 * in all destination drivers can easily be shared, without having to recode
54 * the same stuff multiple times.
55 *
56 * Driver plugins are activated with the "attach" virtual method, which in
57 * turn may redirect any of the LogDriver virtual methods to themselves.
58 * They can even have a "user_data" pointer, so that they can locate their
59 * associated state.
60 *
61 * Multiple plugins can hook into the same method, by saving the original
62 * address & original user_data value.
63 *
64 */
65
66 /* direction agnostic driver class: LogDriver, see specialized source & destination drivers below */
67
68 typedef struct _LogDriver LogDriver;
69 typedef struct _LogDriverPlugin LogDriverPlugin;
70
71 struct _LogDriverPlugin
72 {
73 const gchar *name;
74 /* this function is called when the plugin is attached to a LogDriver
75 * instance. It should do whatever it is necessary to extend the
76 * functionality of the driver specified (e.g. hook into various
77 * methods).
78 */
79
80 gboolean (*attach)(LogDriverPlugin *s, LogDriver *d);
81 void (*detach)(LogDriverPlugin *s, LogDriver *d);
82 void (*free_fn)(LogDriverPlugin *s);
83 };
84
85 static inline gboolean
log_driver_plugin_attach(LogDriverPlugin * self,LogDriver * d)86 log_driver_plugin_attach(LogDriverPlugin *self, LogDriver *d)
87 {
88 return self->attach(self, d);
89 }
90
91 static inline void
log_driver_plugin_detach(LogDriverPlugin * self,LogDriver * d)92 log_driver_plugin_detach(LogDriverPlugin *self, LogDriver *d)
93 {
94 if (self->detach)
95 self->detach(self, d);
96 }
97
98 static inline void
log_driver_plugin_free(LogDriverPlugin * self)99 log_driver_plugin_free(LogDriverPlugin *self)
100 {
101 self->free_fn(self);
102 }
103
104 void log_driver_plugin_init_instance(LogDriverPlugin *self, const gchar *name);
105 void log_driver_plugin_free_method(LogDriverPlugin *self);
106
107 struct _LogDriver
108 {
109 LogPipe super;
110
111 gboolean optional;
112 gchar *group;
113 gchar *id;
114 GList *plugins;
115
116 StatsCounterItem *processed_group_messages;
117
118 };
119
120 gboolean log_driver_add_plugin(LogDriver *self, LogDriverPlugin *plugin);
121 void log_driver_append(LogDriver *self, LogDriver *next);
122 LogDriverPlugin *log_driver_lookup_plugin(LogDriver *self, const gchar *name);
123
124 #define log_driver_get_plugin(self, T, name) \
125 ({ \
126 T *plugin = (T *) log_driver_lookup_plugin(self, name); \
127 g_assert(plugin != NULL); \
128 plugin; \
129 })
130
131 /* methods registered to the init/deinit virtual functions */
132 gboolean log_driver_init_method(LogPipe *s);
133 gboolean log_driver_deinit_method(LogPipe *s);
134
135
136 /* source driver class: LogSourceDriver */
137
138 typedef struct _LogSrcDriver LogSrcDriver;
139
140 struct _LogSrcDriver
141 {
142 LogDriver super;
143 gint group_len;
144 StatsCounterItem *received_global_messages;
145 };
146
147 gboolean log_src_driver_init_method(LogPipe *s);
148 gboolean log_src_driver_deinit_method(LogPipe *s);
149 void log_src_driver_queue_method(LogPipe *s, LogMessage *msg, const LogPathOptions *path_options);
150 void log_src_driver_init_instance(LogSrcDriver *self, GlobalConfig *cfg);
151 void log_src_driver_free(LogPipe *s);
152
153 /* destination driver class: LogDestDriver */
154
155 typedef struct _LogDestDriver LogDestDriver;
156
157 struct _LogDestDriver
158 {
159 LogDriver super;
160
161 LogQueue *(*acquire_queue)(LogDestDriver *s, const gchar *persist_name);
162 void (*release_queue)(LogDestDriver *s, LogQueue *q);
163
164 /* queues managed by this LogDestDriver, all constructed queues come
165 * here and are automatically saved into cfg_persist & persist_state. */
166 GList *queues;
167
168 gint log_fifo_size;
169 gint throttle;
170 StatsCounterItem *queued_global_messages;
171 };
172
173 /* returns a reference */
174 static inline LogQueue *
log_dest_driver_acquire_queue(LogDestDriver * self,const gchar * persist_name)175 log_dest_driver_acquire_queue(LogDestDriver *self, const gchar *persist_name)
176 {
177 LogQueue *q;
178
179 q = self->acquire_queue(self, persist_name);
180 if (q)
181 {
182 self->queues = g_list_prepend(self->queues, q);
183 }
184 return q;
185 }
186
187 /* consumes the reference in @q */
188 static inline void
log_dest_driver_release_queue(LogDestDriver * self,LogQueue * q)189 log_dest_driver_release_queue(LogDestDriver *self, LogQueue *q)
190 {
191 if (q)
192 {
193 self->queues = g_list_remove(self->queues, q);
194
195 /* this drops the reference passed by the caller */
196 self->release_queue(self, q);
197 /* this drops the reference stored on the list */
198 log_queue_unref(q);
199 }
200 }
201
202 gboolean log_dest_driver_init_method(LogPipe *s);
203 gboolean log_dest_driver_deinit_method(LogPipe *s);
204 void log_dest_driver_queue_method(LogPipe *s, LogMessage *msg, const LogPathOptions *path_options);
205
206 void log_dest_driver_init_instance(LogDestDriver *self, GlobalConfig *cfg);
207 void log_dest_driver_free(LogPipe *s);
208
209
210 #endif
211