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