diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2009-04-22 08:53:00 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2009-04-22 08:53:00 +0200 |
commit | b0cfe39c851de0851d88e1b6a51bf40a76fb8304 (patch) | |
tree | ab070405208c807123440e5c17b69e960225b465 | |
parent | 83c40e8838a2b64a3fdb02196944302533079d2a (diff) | |
parent | 029218df5b7fbd6a7e4f945ecd32f84236885f53 (diff) | |
download | rsyslog-b0cfe39c851de0851d88e1b6a51bf40a76fb8304.tar.gz rsyslog-b0cfe39c851de0851d88e1b6a51bf40a76fb8304.tar.xz rsyslog-b0cfe39c851de0851d88e1b6a51bf40a76fb8304.zip |
Merge branch 'master' into multi-dequeue
36 files changed, 446 insertions, 52 deletions
@@ -1,5 +1,11 @@ --------------------------------------------------------------------------- -Version 4.3.0 [DEVEL] (rgerhards), 2009-03-?? +Version 4.3.1 [DEVEL] (rgerhards), 2009-04-?? +- improved doc + * added (hopefully) easier to grasp queue explanation +- improved testbench + * added tests for queue disk-only mode (checks disk queue logic) +--------------------------------------------------------------------------- +Version 4.3.0 [DEVEL] (rgerhards), 2009-04-17 - new feature: new output plugin omprog, which permits to start program and feed it (via its stdin) with syslog messages. If the program terminates, it is restarted. @@ -14,6 +20,11 @@ Version 4.3.0 [DEVEL] (rgerhards), 2009-03-?? - added $MaxOpenFiles configuration directive - bugfix: solved potential memory leak in msg processing, could manifest itself in imtcp +- bugfix: ompgsql did not detect problems in sql command execution + this could cause loss of messages. The handling was correct if the + connection broke, but not if there was a problem with statement + execution. The most probable case for such a case would be invalid + sql inside the template, and this is now much easier to diagnose. --------------------------------------------------------------------------- Version 4.1.7 [BETA] (rgerhards), 2009-04-?? - bugfix: $InputTCPMaxSessions config directive was accepted, but not @@ -21,6 +32,11 @@ Version 4.1.7 [BETA] (rgerhards), 2009-04-?? - bugfix: the default for $DirCreateMode was 0644, and as such wrong. It has now been changed to 0700. For some background, please see http://lists.adiscon.net/pipermail/rsyslog/2009-April/001986.html +- bugfix: ompgsql did not detect problems in sql command execution + this could cause loss of messages. The handling was correct if the + connection broke, but not if there was a problem with statement + execution. The most probable case for such a case would be invalid + sql inside the template, and this is now much easier to diagnose. --------------------------------------------------------------------------- Version 4.1.6 [DEVEL] (rgerhards), 2009-04-07 - added new "csv" property replacer options to enable simple creation @@ -158,12 +174,19 @@ version before switching to this one. - bugfix: memory leak in ompgsql Thanks to Ken for providing the patch --------------------------------------------------------------------------- -Version 3.22.0 [v3-stable] (rgerhards), 2009-04-?? +Version 3.22.0 [v3-stable] (rgerhards), 2009-04-21 +This is the first stable release that includes the full functionality +of the 3.21.x version tree. - bugfix: $InputTCPMaxSessions config directive was accepted, but not honored. This resulted in a fixed upper limit of 200 connections. - bugfix: the default for $DirCreateMode was 0644, and as such wrong. It has now been changed to 0700. For some background, please see http://lists.adiscon.net/pipermail/rsyslog/2009-April/001986.html +- bugfix: ompgsql did not detect problems in sql command execution + this could cause loss of messages. The handling was correct if the + connection broke, but not if there was a problem with statement + execution. The most probable case for such a case would be invalid + sql inside the template, and this is now much easier to diagnose. --------------------------------------------------------------------------- Version 3.21.11 [BETA] (rgerhards), 2009-04-03 - build system improvements contributed by Michael Biebl - thx! @@ -1258,6 +1281,13 @@ Version 3.10.0 (rgerhards), 2008-01-07 - much cleaner code due to new objects and removal of single-threading mode --------------------------------------------------------------------------- +Version 2.0.8 V2-STABLE (rgerhards), 2008-??-?? +- bugfix: ompgsql did not detect problems in sql command execution + this could cause loss of messages. The handling was correct if the + connection broke, but not if there was a problem with statement + execution. The most probable case for such a case would be invalid + sql inside the template, and this is now much easier to diagnose. +--------------------------------------------------------------------------- Version 2.0.7 V2-STABLE (rgerhards), 2008-04-14 - bugfix: the default for $DirCreateMode was 0644, and as such wrong. It has now been changed to 0700. For some background, please see diff --git a/configure.ac b/configure.ac index c7f1d532..6daf3f5a 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([rsyslog],[4.1.6],[rsyslog@lists.adiscon.com]) +AC_INIT([rsyslog],[4.3.0],[rsyslog@lists.adiscon.com]) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([ChangeLog]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/Makefile.am b/doc/Makefile.am index 0f3dca70..4d9d94ff 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -109,6 +109,20 @@ html_files = \ rsyslog_conf_output.html \ rsyslog_conf_templates.html \ rsyslog_conf_nomatch.html \ + queues_analogy.html \ src/classes.dia -EXTRA_DIST = $(html_files) +grfx_files = \ + direct_queue0.png \ + direct_queue1.png \ + direct_queue2.png \ + direct_queue3.png \ + direct_queue_rsyslog.png \ + direct_queue_rsyslog2.png \ + direct_queue_directq.png \ + dataflow.png \ + queue_analogy_tv.png \ + gssapi.png \ + rsyslog-vers.png + +EXTRA_DIST = $(html_files) $(grfx_files) diff --git a/doc/dataflow.png b/doc/dataflow.png Binary files differnew file mode 100644 index 00000000..fd614d8c --- /dev/null +++ b/doc/dataflow.png diff --git a/doc/direct_queue0.png b/doc/direct_queue0.png Binary files differnew file mode 100644 index 00000000..6d1b373f --- /dev/null +++ b/doc/direct_queue0.png diff --git a/doc/direct_queue1.png b/doc/direct_queue1.png Binary files differnew file mode 100644 index 00000000..503f8151 --- /dev/null +++ b/doc/direct_queue1.png diff --git a/doc/direct_queue2.png b/doc/direct_queue2.png Binary files differnew file mode 100644 index 00000000..cbb99af8 --- /dev/null +++ b/doc/direct_queue2.png diff --git a/doc/direct_queue3.png b/doc/direct_queue3.png Binary files differnew file mode 100644 index 00000000..cc49299f --- /dev/null +++ b/doc/direct_queue3.png diff --git a/doc/direct_queue_directq.png b/doc/direct_queue_directq.png Binary files differnew file mode 100644 index 00000000..c5d8769d --- /dev/null +++ b/doc/direct_queue_directq.png diff --git a/doc/direct_queue_rsyslog.png b/doc/direct_queue_rsyslog.png Binary files differnew file mode 100644 index 00000000..6150222d --- /dev/null +++ b/doc/direct_queue_rsyslog.png diff --git a/doc/direct_queue_rsyslog2.png b/doc/direct_queue_rsyslog2.png Binary files differnew file mode 100644 index 00000000..807b064d --- /dev/null +++ b/doc/direct_queue_rsyslog2.png diff --git a/doc/manual.html b/doc/manual.html index 51271701..ae90f780 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -19,7 +19,7 @@ rsyslog support</a> available directly from the source!</p> <p><b>Please visit the <a href="http://www.rsyslog.com/sponsors">rsyslog sponsor's page</a> to honor the project sponsors or become one yourself!</b> We are very grateful for any help towards the project goals.</p> -<p><b>This documentation is for version 4.1.6 (devel branch) of rsyslog.</b> +<p><b>This documentation is for version 4.3.0 (devel branch) of rsyslog.</b> Visit the <i> <a href="http://www.rsyslog.com/doc-status.html">rsyslog status page</a></i></b> to obtain current version information and project status. </p><p><b>If you like rsyslog, you might diff --git a/doc/queue_analogy_tv.png b/doc/queue_analogy_tv.png Binary files differnew file mode 100644 index 00000000..fedcb558 --- /dev/null +++ b/doc/queue_analogy_tv.png diff --git a/doc/queues.html b/doc/queues.html index 41c5865f..4a9509a0 100644 --- a/doc/queues.html +++ b/doc/queues.html @@ -1,6 +1,5 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head> -<meta http-equiv="Content-Language" content="de"> <title>Understanding rsyslog queues</title></head> <body> <a href="rsyslog_conf_global.html">back</a> @@ -10,6 +9,13 @@ queue, one part of the system "produces" something while another part "consumes" this something. The "something" is most often syslog messages, but queues may also be used for other purposes.</p> +<p>This document provides a good insight into technical details, operation modes +and implications. In addition to it, an +<a href="queues_analogy.html">rsyslog queue concepts overview</a> document +exists which tries to explain queues with the help of some analogies. This may +probably be a better place to start reading about queues. I assume that once you +have understood that document, the material here will be much easier to grasp +and look much more natural. <p>The most prominent example is the main message queue. Whenever rsyslog receives a message (e.g. locally, via UDP, TCP or in whatever else way), it places these messages into the main message queue. Later, it is dequeued by the @@ -18,7 +24,7 @@ front of each action, there is also a queue, which potentially de-couples the filter processing from the actual action (e.g. writing to file, database or forwarding to another host).</p> <h1>Where are Queues Used?</h1> -<p> Currently, queues are used for the main message queue and for the +<p>Currently, queues are used for the main message queue and for the actions.</p> <p>There is a single main message queue inside rsyslog. Each input module delivers messages to it. The main message queue worker filters messages based on @@ -354,8 +360,8 @@ save.</p> [<a href="http://www.rsyslog.com/">rsyslog site</a>]</p> <p><font size="2">This documentation is part of the <a href="http://www.rsyslog.com/">rsyslog</a> project.<br> -Copyright © 2008 by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a> and +Copyright © 2008, 2009 by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a> and <a href="http://www.adiscon.com/">Adiscon</a>. Released under the GNU GPL -version 2 or higher.</font></p> +version 3 or higher.</font></p> </body></html> diff --git a/doc/queues_analogy.html b/doc/queues_analogy.html new file mode 100644 index 00000000..d7533ad5 --- /dev/null +++ b/doc/queues_analogy.html @@ -0,0 +1,259 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html><head> +<title>turning lanes and rsyslog queues - an analogy</title></head> +<body> +<a href="rsyslog_conf_global.html">back</a> + +<h1>Turning Lanes and Rsyslog Queues - an Analogy</h1> +<p>If there is a single object absolutely vital to understanding the way +rsyslog works, this object is queues. Queues offer a variety of services, +including support for multithreading. While there is elaborate in-depth +documentation on the ins and outs of <a href="queues.html">rsyslog queues</a>, +some of the concepts are hard to grasp even for experienced people. I think this +is because rsyslog uses a very high layer of abstraction which includes things +that look quite unnatural, like queues that do <b>not</b> actually queue... +<p>With this document, I take a different approach: I will not describe every specific +detail of queue operation but hope to be able to provide the core idea of how +queues are used in rsyslog by using an analogy. I will compare the rsyslog data flow +with real-life traffic flowing at an intersection. +<p>But first let's set the stage for the rsyslog part. The graphic below describes +the data flow inside rsyslog: +<p align="center"><img src="dataflow.png" alt="rsyslog data flow"> +<p>Note that there is a <a href="http://www.rsyslog.com/Article350.phtml">video tutorial</a> +available on the data flow. It is not perfect, but may aid in understanding this picture. +<p>For our needs, the important fact to know is that messages enter rsyslog on "the +left side" (for example, via UDP), are being preprocessed, put into the +so-called main queue, taken off that queue, be filtered and be placed into one or +several action queues (depending on filter results). They leave rsyslog on "the +right side" where output modules (like the file or database writer) consume them. +<p>So there are always <b>two</b> stages where a message (conceptually) is queued - first +in the main queue and later on in <i>n</i> action specific queues (with <i>n</i> being the number of +actions that the message in question needs to be processed by, what is being decided +by the "Filter Engine"). As such, a message will be in at least two queues +during its lifetime (with the exception of messages being discarded by the queue itself, +but for the purpose of this document, we will ignore that possibility). +<p>Also, it is vitally +important to understand that <b>each</b> action has a queue sitting in front of it. +If you have dug into the details of rsyslog configuration, you have probably seen that +a queue mode can be set for each action. And the default queue mode is the so-called +"direct mode", in which "the queue does not actually enqueue data". +That sounds silly, but is not. It is an important abstraction that helps keep the code clean. +<p>To understand this, we first need to look at who is the active component. In our data flow, +the active part always sits to the left of the object. For example, the "Preprocessor" +is being called by the inputs and calls itself into the main message queue. That is, the queue +receiver is called, it is passive. One might think that the "Parser & Filter Engine" +is an active component that actively pulls messages from the queue. This is wrong! Actually, +it is the queue that has a pool of worker threads, and these workers pull data from the queue +and then call the passively waiting Parser and Filter Engine with those messages. So the +main message queue is the active part, the Parser and Filter Engine is passive. +<p>Let's now try an analogy analogy for this part: Think about a TV show. The show is produced +in some TV studio, from there sent (actively) to a radio tower. The radio tower passively +receives from the studio and then actively sends out a signal, which is passively received +by your TV set. In our simplified view, we have the following picture: +<p align="center"><img src="queue_analogy_tv.png" alt="rsyslog queues and TV analogy"> +<p>The lower part of the picture lists the equivalent rsyslog entities, in an abstracted way. +Every queue has a producer (in the above sample the input) and a consumer (in the above sample the Parser +and Filter Engine). Their active and passive functions are equivalent to the TV entities +that are listed on top of the rsyslog entity. For example, a rsyslog consumer can never +actively initiate reception of a message in the same way a TV set cannot actively +"initiate" a TV show - both can only "handle" (display or process) +what is sent to them. +<p>Now let's look at the action queues: here, the active part, the producer, is the +Parser and Filter Engine. The passive part is the Action Processor. The later does any +processing that is necessary to call the output plugin, in particular it processes the template +to create the plugin calling parameters (either a string or vector of arguments). From the +action queue's point of view, Action Processor and Output form a single entity. Again, the +TV set analogy holds. The Output <b>does not</b> actively ask the queue for data, but +rather passively waits until the queue itself pushes some data to it. + +<p>Armed with this knowledge, we can now look at the way action queue modes work. My analogy here +is a junction, as shown below (note that the colors in the pictures below are <b>not</b> related to +the colors in the pictures above!): +<p align="center"><img src="direct_queue0.png"> +<p>This is a very simple real-life traffic case: one road joins another. We look at +traffic on the straight road, here shown by blue and green arrows. Traffic in the +opposing direction is shown in blue. Traffic flows without +any delays as long as nobody takes turns. To be more precise, if the opposing traffic takes +a (right) turn, traffic still continues to flow without delay. However, if a car in the red traffic +flow intends to do a (left, then) turn, the situation changes: +<p align="center"><img src="direct_queue1.png"> +<p>The turning car is represented by the green arrow. It cannot turn unless there is a gap +in the "blue traffic stream". And as this car blocks the roadway, the remaining +traffic (now shown in red, which should indicate the block condition), +must wait until the "green" car has made its turn. So +a queue will build up on that lane, waiting for the turn to be completed. +Note that in the examples below I do not care that much about the properties of the +opposing traffic. That is, because its structure is not really important for what I intend to +show. Think about the blue arrow as being a traffic stream that most of the time blocks +left-turners, but from time to time has a gap that is sufficiently large for a left-turn +to complete. +<p>Our road network designers know that this may be unfortunate, and for more important roads +and junctions, they came up with the concept of turning lanes: +<p align="center"><img src="direct_queue2.png"> +<p>Now, the car taking the turn can wait in a special area, the turning lane. As such, +the "straight" traffic is no longer blocked and can flow in parallel to the +turning lane (indicated by a now-green-again arrow). + +<p>However, the turning lane offers only finite space. So if too many cars intend to +take a left turn, and there is no gap in the "blue" traffic, we end up with +this well-known situation: +<p align="center"><img src="direct_queue3.png"> +<p>The turning lane is now filled up, resulting in a tailback of cars intending to +left turn on the main driving lane. The end result is that "straight" traffic +is again being blocked, just as in our initial problem case without the turning lane. +In essence, the turning lane has provided some relief, but only for a limited amount of +cars. Street system designers now try to weight cost vs. benefit and create (costly) +turning lanes that are sufficiently large to prevent traffic jams in most, but not all +cases. +<p><b>Now let's dig a bit into the mathematical properties of turning lanes.</b> We assume that +cars all have the same length. So, units of cars, the length is alsways one (which is nice, +as we don't need to care about that factor any longer ;)). A turning lane has finite capacity of +<i>n</i> cars. As long as the number of cars wanting to take a turn is less than or eqal +to <i>n</i>, "straigth traffic" is not blocked (or the other way round, traffic +is blocked if at least <i>n + 1</i> cars want to take a turn!). We can now find an optimal +value for <i>n</i>: it is a function of the probability that a car wants to turn +and the cost of the turning lane +(as well as the probability there is a gap in the "blue" traffic, but we ignore this +in our simple sample). +If we start from some finite upper bound of <i>n</i>, we can decrease +<i>n</i> to a point where it reaches zero. But let's first look at <i>n = 1</i>, in which case exactly +one car can wait on the turning lane. More than one car, and the rest of the traffic is blocked. +Our everyday logic indicates that this is actually the lowest boundary for <i>n</i>. +<p>In an abstract view, however, <i>n</i> can be zero and that works nicely. There still can be +<i>n</i> cars at any given time on the turning lane, it just happens that this means there can +be no car at all on it. And, as usual, if we have at least <i>n + 1</i> cars wanting to turn, +the main traffic flow is blocked. True, but <i>n + 1 = 0 + 1 = 1</i> so as soon as there is any +car wanting to take a turn, the main traffic flow is blocked (remember, in all cases, I assume +no sufficiently large gaps in the opposing traffic). +<p>This is the situation our everyday perception calls "road without turning lane". +In my math model, it is a "road with turning lane of size 0". The subtle difference +is important: my math model guarantees that, in an abstract sense, there always is a turning +lane, it may just be too short. But it exists, even though we don't see it. And now I can +claim that even in my small home village, all roads have turning lanes, which is rather +impressive, isn't it? ;) +<p><b>And now we finally have arrived at rsyslog's queues!</b> Rsyslog action queues exists for +all actions just like all roads in my village have turning lanes! And as in this real-life sample, +it may be hard to see the action queues for that reason. In rsyslog, the "direct" queue +mode is the equivalent to the 0-sized turning lane. And actions queues are the equivalent to turning +lanes in general, with our real-life <i>n</i> being the maximum queue size. +The main traffic line (which sometimes is blocked) is the equivalent to the +main message queue. And the periods without gaps in the opposing traffic are equivalent to +execution time of an action. In a rough sketch, the rsyslog main and action queues look like in the +following picture. +<p align="center"><img src="direct_queue_rsyslog.png"> +<p>We need to read this picture from right to left (otherwise I would need to redo all +the graphics ;)). In action 3, you see a 0-sized turning lane, aka an action queue in "direct" +mode. All other queues are run in non-direct modes, but with different sizes greater than 0. +<p>Let us first use our car analogy: +Assume we are in a car on the main lane that wants to take turn into the "action 4" +road. We pass action 1, where a number of cars wait in the turning lane and we pass +action 2, which has a slightly smaller, but still not filled up turning lane. So we pass that +without delay, too. Then we come to "action 3", which has no turning lane. Unfortunately, +the car in front of us wants to turn left into that road, so it blocks the main lane. So, this time +we need to wait. An observer standing on the sidewalk may see that while we need to wait, there are +still some cars in the "action 4" turning lane. As such, even though no new cars can +arrive on the main lane, cars still turn into the "action 4" lane. In other words, +an observer standing in "action 4" road is unable to see that traffic on the main lane +is blocked. +<p>Now on to rsyslog: Other than in the real-world traffic example, messages in rsyslog +can - at more or less the +same time - "take turns" into several roads at once. This is done by duplicating the message +if the road has a non-zero-sized "turning lane" - or in rsyslog terms a queue that is +running in any non-direct mode. If so, a deep copy of the message object is made, that placed into +the action queue and then the initial message proceeds on the "main lane". The action +queue then pushes the duplicates through action processing. This is also the reason why a +discard action inside a non-direct queue does not seem to have an effect. Actually, it discards the +copy that was just created, but the original message object continues to flow. +<p> +In action 1, we have some entries in the action queue, as we have in action 2 (where the queue is +slightly shorter). As we have seen, new messages pass action one and two almost instantaneously. +However, when a messages reaches action 3, its flow is blocked. Now, message processing must wait +for the action to complete. Processing flow in a direct mode queue is something like a U-turn: + +<p align="center"><img src="direct_queue_directq.png" alt="message processing in an rsyslog action queue in direct mode"> +<p>The message starts to execute the action and once this is done, processing flow continues. +In a real-life analogy, this may be the route of a delivery man who needs to drop a parcel +in a side street before he continues driving on the main route. As a side-note, think of what happens +with the rest of the delivery route, at least for today, if the delivery truck has a serious accident +in the side street. The rest of the parcels won't be delivered today, will they? This is exactly how the +discard action works. It drops the message object inside the action and thus the message will no +longer be available for further delivery - but as I said, only if the discard is done in a +direct mode queue (I am stressing this example because it often causes a lot of confusion). +<p>Back to the overall scenario. We have seen that messages need to wait for action 3 to +complete. Does this necessarily mean that at the same time no messages can be processed +in action 4? Well, it depends. As in the real-life scenario, action 4 will continue to +receive traffic as long as its action queue ("turn lane") is not drained. In +our drawing, it is not. So action 4 will be executed while messages still wait for action 3 +to be completed. +<p>Now look at the overall picture from a slightly different angle: +<p align="center"><img src="direct_queue_rsyslog2.png" alt="message processing in an rsyslog action queue in direct mode"> +<p>The number of all connected green and red arrows is four - one each for action 1, 2 and 3 +(this one is dotted as action 4 was a special case) and one for the "main lane" as +well as action 3 (this one contains the sole red arrow). <b>This number is the lower bound for +the number of threads in rsyslog's output system ("right-hand part" of the main message +queue)!</b> Each of the connected arrows is a continuous thread and each "turn lane" is +a place where processing is forked onto a new thread. Also, note that in action 3 the processing +is carried out on the main thread, but not in the non-direct queue modes. +<p>I have said this is "the lower bound for the number of threads...". This is with +good reason: the main queue may have more than one worker thread (individual action queues +currently do not support this, but could do in the future - there are good reasons for that, too +but exploring why would finally take us away from what we intend to see). Note that you +configure an upper bound for the number of main message queue worker threads. The actual number +varies depending on a lot of operational variables, most importantly the number of messages +inside the queue. The number <i>t_m</i> of actually running threads is within the integer-interval +[0,confLimit] (with confLimit being the operator configured limit, which defaults to 5). +Output plugins may have more than one thread created by themselves. It is quite unusual for an +output plugin to create such threads and so I assume we do not have any of these. +Then, the overall number of threads in rsyslog's filtering and output system is +<i>t_total = t_m + number of actions in non-direct modes</i>. Add the number of +inputs configured to that and you have the total number of threads running in rsyslog at +a given time (assuming again that inputs utilize only one thread per plugin, a not-so-safe +assumption). +<p>A quick side-note: I gave the lower bound for <i>t_m</i> as zero, which is somewhat in contrast +to what I wrote at the begin of the last paragraph. Zero is actually correct, because rsyslog +stops all worker threads when there is no work to do. This is also true for the action queues. +So the ultimate lower bound for a rsyslog output system without any work to carry out actually is zero. +But this bound will never be reached when there is continuous flow of activity. And, if you are +curios: if the number of workers is zero, the worker wakeup process is actually handled within the +threading context of the "left-hand-side" (or producer) of the queue. After being +started, the worker begins to play the active queue component again. All of this, of course, +can be overridden with configuration directives. +<p>When looking at the threading model, one can simply add n lanes to the main lane but otherwise +retain the traffic analogy. This is a very good description of the actual process (think what this +means to the "turning lanes"; hint: there still is only one per action!). +<p><b>Let's try to do a warp-up:</b> I have hopefully been able to show that in rsyslog, an action +queue "sits in front of" each output plugin. Messages are received and flow, from input +to output, over various stages and two level of queues to the outputs. Actions queues are always +present, but may not easily be visible when in direct mode (where no actual queuing takes place). +The "road junction with turning lane" analogy well describes the way - and intent - of the various +queue levels in rsyslog. +<p>On the output side, the queue is the active component, <b>not</b> the consumer. As such, the consumer +cannot ask the queue for anything (like n number of messages) but rather is activated by the queue +itself. As such, a queue somewhat resembles a "living thing" whereas the outputs are +just tools that this "living thing" uses. +<p><b>Note that I left out a couple of subtleties</b>, especially when it comes +to error handling and terminating +a queue (you hopefully have now at least a rough idea why I say "terminating <b>a queue</b>" +and not "terminating an action" - <i>who is the "living thing"?</i>). An action returns +a status to the queue, but it is the queue that ultimately decides which messages can finally be +considered processed and which not. Please note that the queue may even cancel an output right in +the middle of its action. This happens, if configured, if an output needs more than a configured +maximum processing time and is a guard condition to prevent slow outputs from deferring a rsyslog +restart for too long. Especially in this case re-queuing and cleanup is not trivial. Also, note that +I did not discuss disk-assisted queue modes. The basic rules apply, but there are some additional +constraints, especially in regard to the threading model. Transitioning between actual +disk-assisted mode and pure-in-memory-mode (which is done automatically when needed) is also far from +trivial and a real joy for an implementer to work on ;). +<p>If you have not done so before, it may be worth reading the +<a href="queues.html">rsyslog queue user's guide,</a> which most importantly lists all +the knobs you can turn to tweak queue operation. +<p>[<a href="manual.html">manual index</a>] +[<a href="rsyslog_conf.html">rsyslog.conf</a>] +[<a href="http://www.rsyslog.com/">rsyslog site</a>]</p> +<p><font size="2">This documentation is part of the +<a href="http://www.rsyslog.com/">rsyslog</a> project.<br> +Copyright © 2009 by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a> and +<a href="http://www.adiscon.com/">Adiscon</a>. Released under the GNU GPL +version 3 or higher.</font></p> +</body> +</html> diff --git a/doc/src/dataflow.dia b/doc/src/dataflow.dia Binary files differnew file mode 100644 index 00000000..3875fc61 --- /dev/null +++ b/doc/src/dataflow.dia diff --git a/doc/src/direct_queue0.dia b/doc/src/direct_queue0.dia Binary files differnew file mode 100644 index 00000000..4446619b --- /dev/null +++ b/doc/src/direct_queue0.dia diff --git a/doc/src/direct_queue1.dia b/doc/src/direct_queue1.dia Binary files differnew file mode 100644 index 00000000..7a64ea09 --- /dev/null +++ b/doc/src/direct_queue1.dia diff --git a/doc/src/direct_queue2.dia b/doc/src/direct_queue2.dia Binary files differnew file mode 100644 index 00000000..b0c394c0 --- /dev/null +++ b/doc/src/direct_queue2.dia diff --git a/doc/src/direct_queue3.dia b/doc/src/direct_queue3.dia Binary files differnew file mode 100644 index 00000000..bc477b25 --- /dev/null +++ b/doc/src/direct_queue3.dia diff --git a/doc/src/direct_queue_directq.dia b/doc/src/direct_queue_directq.dia Binary files differnew file mode 100644 index 00000000..37fdb44c --- /dev/null +++ b/doc/src/direct_queue_directq.dia diff --git a/doc/src/direct_queue_rsyslog.dia b/doc/src/direct_queue_rsyslog.dia Binary files differnew file mode 100644 index 00000000..9a030117 --- /dev/null +++ b/doc/src/direct_queue_rsyslog.dia diff --git a/doc/src/direct_queue_rsyslog2.dia b/doc/src/direct_queue_rsyslog2.dia Binary files differnew file mode 100644 index 00000000..c596f39f --- /dev/null +++ b/doc/src/direct_queue_rsyslog2.dia diff --git a/doc/src/queue_analogy_tv.dia b/doc/src/queue_analogy_tv.dia Binary files differnew file mode 100644 index 00000000..00fbdeb5 --- /dev/null +++ b/doc/src/queue_analogy_tv.dia diff --git a/doc/status.html b/doc/status.html index fff3a6ff..c8608f73 100644 --- a/doc/status.html +++ b/doc/status.html @@ -2,22 +2,22 @@ <html><head><title>rsyslog status page</title></head> <body> <h2>rsyslog status page</h2> -<p>This page reflects the status as of 2009-04-03.</p> +<p>This page reflects the status as of 2009-04-21.</p> <h2>Current Releases</h2> -<p><b>development:</b> 4.1.6 [2009-04-07] - -<a href="http://www.rsyslog.com/Article360.phtml">change log</a> - -<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-153.phtml">download</a> +<p><b>development:</b> 4.3.0 [2009-04-17] - +<a href="http://www.rsyslog.com/Article366.phtml">change log</a> - +<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-156.phtml">download</a> <br><b>beta:</b> 3.21.11 [2009-04-03] - <a href="http://www.rsyslog.com/Article358.phtml">change log</a> - <a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-152.phtml">download</a></p> -<p><b>v3 stable:</b> 3.20.5 [2009-04-02] - <a href="http://www.rsyslog.com/Article356.phtml">change log</a> - -<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-151.phtml">download</a> +<p><b>v3 stable:</b> 3.22.0 [2009-04-21] - <a href="http://www.rsyslog.com/Article368.phtml">change log</a> - +<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-157.phtml">download</a> -<br><b>v2 stable:</b> 2.0.6 [2008-08-07] - <a href="http://www.rsyslog.com/Article266.phtml">change log</a> - -<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-125.phtml">download</a> +<br><b>v2 stable:</b> 2.0.7 [2009-04-14] - <a href="http://www.rsyslog.com/Article362.phtml">change log</a> - +<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-154.phtml">download</a> <br>v0 and v1 are deprecated and no longer supported. If you absolutely do not like to upgrade, you may consider purchasing a <a href="professional_support.html">commercial rsyslog support package</a>. Just let us point diff --git a/plugins/imgssapi/imgssapi.c b/plugins/imgssapi/imgssapi.c index debe935e..b9d7dfe3 100644 --- a/plugins/imgssapi/imgssapi.c +++ b/plugins/imgssapi/imgssapi.c @@ -249,7 +249,6 @@ onErrClose(tcps_sess_t *pSess) static rsRetVal doOpenLstnSocks(tcpsrv_t *pSrv) { - int *pRet = NULL; gsssrv_t *pGSrv; DEFiRet; diff --git a/plugins/imklog/ksym_mod.c b/plugins/imklog/ksym_mod.c index 6e48e89e..be5fdee9 100644 --- a/plugins/imklog/ksym_mod.c +++ b/plugins/imklog/ksym_mod.c @@ -1,9 +1,8 @@ -/* - * ksym_mod.c - functions for building symbol lookup tables for klogd +/* ksym_mod.c - functions for building symbol lookup tables for klogd * Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com> * Copyright (c) 1996 Enjellic Systems Development * Copyright (c) 1998-2007 Martin Schulze <joey@infodrom.org> - * Copyright (C) 2007-2008 Rainer Gerhards <rgerhards@adiscon.com> + * Copyright (C) 2007-2009 Rainer Gerhards <rgerhards@adiscon.com> * * This file is part of rsyslog. * @@ -83,7 +82,6 @@ * Changed llseek() to lseek64() in order to skip a libc warning. */ - /* Includes. */ #include "config.h" #include <stdio.h> @@ -112,7 +110,7 @@ #define KSYMS "/proc/kallsyms" static int num_modules = 0; -struct Module *sym_array_modules = (struct Module *) 0; +struct Module *sym_array_modules = (struct Module *) NULL; static int have_modules = 0; @@ -266,7 +264,7 @@ static void FreeModules() } free(sym_array_modules); - sym_array_modules = (struct Module *) 0; + sym_array_modules = (struct Module *) NULL; num_modules = 0; return; } @@ -390,11 +388,11 @@ static int AddSymbol(line) mp->sym_array = (struct sym_table *) realloc(mp->sym_array, \ (mp->num_syms+1) * sizeof(struct sym_table)); - if ( mp->sym_array == (struct sym_table *) 0 ) + if ( mp->sym_array == (struct sym_table *) NULL ) return(0); mp->sym_array[mp->num_syms].name = strdup(p); - if ( mp->sym_array[mp->num_syms].name == (char *) 0 ) + if ( mp->sym_array[mp->num_syms].name == (char *) NULL ) return(0); /* Stuff interesting information into the module. */ @@ -424,15 +422,21 @@ static int AddSymbol(line) * If a match cannot be found a diagnostic string is printed. * If a match is found the pointer to the symbolic name most * closely matching the address is returned. + * + * TODO: We are using int values for the offset, but longs for the value + * values. This may create some trouble in the future (on 64 Bit OS?). + * Anyhow, I have not changed this, because we do not seem to have any + * issue and my understanding of this code is limited (and I don't see + * need to invest more time to dig much deeper). + * rgerhards, 2009-04-17 **************************************************************************/ extern char * LookupModuleSymbol(value, sym) unsigned long value; struct symbol *sym; { - auto int nmod, - nsym; - auto struct sym_table *last; - auto struct Module *mp; + int nmod, nsym; + struct sym_table *last; + struct Module *mp; static char ret[100]; sym->size = 0; @@ -443,8 +447,7 @@ extern char * LookupModuleSymbol(value, sym) for (nmod = 0; nmod < num_modules; ++nmod) { mp = &sym_array_modules[nmod]; - /* - * Run through the list of symbols in this module and + /* Run through the list of symbols in this module and * see if the address can be resolved. */ for(nsym = 1, last = &mp->sym_array[0]; @@ -453,13 +456,12 @@ extern char * LookupModuleSymbol(value, sym) if ( mp->sym_array[nsym].value > value ) { if ( sym->size == 0 || - (value - last->value) < sym->offset || - ( (sym->offset == (value - last->value)) && - (mp->sym_array[nsym].value-last->value) < sym->size ) ) + (int) (value - last->value) < sym->offset || + ( (sym->offset == (int) (value - last->value)) && + (int) (mp->sym_array[nsym].value-last->value) < sym->size ) ) { sym->offset = value - last->value; - sym->size = mp->sym_array[nsym].value - \ - last->value; + sym->size = mp->sym_array[nsym].value - last->value; ret[sizeof(ret)-1] = '\0'; if ( mp->name == NULL ) snprintf(ret, sizeof(ret)-1, @@ -478,5 +480,5 @@ extern char * LookupModuleSymbol(value, sym) return(ret); /* It has been a hopeless exercise. */ - return((char *) 0); + return(NULL); } diff --git a/plugins/imklog/ksyms.h b/plugins/imklog/ksyms.h index b5362ff3..a168947b 100644 --- a/plugins/imklog/ksyms.h +++ b/plugins/imklog/ksyms.h @@ -2,7 +2,7 @@ * Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com> * Copyright (c) 1996 Enjellic Systems Development * Copyright (c) 2004-7 Martin Schulze <joey@infodrom.org> - * Copyright (c) 2007-2008 Rainer Gerhards <rgerhards@adiscon.com> + * Copyright (c) 2007-2009 Rainer Gerhards <rgerhards@adiscon.com> * * This file is part of rsyslog. * @@ -26,7 +26,7 @@ struct symbol { - char *name; + uchar *name; int size; int offset; }; diff --git a/plugins/omgssapi/omgssapi.c b/plugins/omgssapi/omgssapi.c index e0cc8af6..361f657f 100644 --- a/plugins/omgssapi/omgssapi.c +++ b/plugins/omgssapi/omgssapi.c @@ -444,7 +444,7 @@ CODESTARTdoAction /* error! */ dbgprintf("error forwarding via tcp, suspending\n"); pData->eDestState = eDestFORW_SUSP; - iRet = RS_RET_SUSPENDED; + ABORT_FINALIZE(RS_RET_SUSPENDED); } break; } diff --git a/plugins/ompgsql/ompgsql.c b/plugins/ompgsql/ompgsql.c index 7658f036..6daac1c7 100644 --- a/plugins/ompgsql/ompgsql.c +++ b/plugins/ompgsql/ompgsql.c @@ -6,7 +6,11 @@ * * File begun on 2007-10-18 by sur5r (converted from ommysql.c) * - * Copyright 2007 Rainer Gerhards and Adiscon GmbH. + * Copyright 2007, 2009 Rainer Gerhards and Adiscon GmbH. + * + * The following link my be useful for the not-so-postgres literate + * when setting up a test environment (on Fedora): + * http://www.jboss.org/community/wiki/InstallPostgreSQLonFedora * * This file is part of rsyslog. * @@ -154,26 +158,55 @@ static rsRetVal initPgSQL(instanceData *pData, int bSilent) } +/* try the insert into postgres and return if that failed or not + * (1 = had error, 0=ok). We do not use the standard IRET calling convention + * rgerhards, 2009-04-17 + */ +static inline int +tryExec(uchar *pszCmd, instanceData *pData) +{ + PGresult *pgRet; + ExecStatusType execState; + int bHadError = 0; + + /* try insert */ + pgRet = PQexec(pData->f_hpgsql, (char*)pszCmd); + execState = PQresultStatus(pgRet); + if(execState != PGRES_COMMAND_OK && execState != PGRES_TUPLES_OK) { + dbgprintf("postgres query execution failed: %s\n", PQresStatus(PQresultStatus(pgRet))); + bHadError = 1; + } + PQclear(pgRet); + + return(bHadError); +} + + /* The following function writes the current log entry * to an established PgSQL session. + * Enhanced function to take care of the returned error + * value (if there is such). Note that this may happen due to + * a sql format error - connection aborts were properly handled + * before my patch. -- rgerhards, 2009-04-17 */ rsRetVal writePgSQL(uchar *psz, instanceData *pData) { + int bHadError = 0; DEFiRet; assert(psz != NULL); assert(pData != NULL); - dbgprintf("writePgSQL: %s", psz); + dbgprintf("writePgSQL: %s\n", psz); - /* try insert */ - PQclear(PQexec(pData->f_hpgsql, (char*)psz)); - if(PQstatus(pData->f_hpgsql) != CONNECTION_OK) { + bHadError = tryExec(psz, pData); /* try insert */ + + if(bHadError || (PQstatus(pData->f_hpgsql) != CONNECTION_OK)) { /* error occured, try to re-init connection and retry */ closePgSQL(pData); /* close the current handle */ CHKiRet(initPgSQL(pData, 0)); /* try to re-open */ - PQclear(PQexec(pData->f_hpgsql, (char*)psz)); - if(PQstatus(pData->f_hpgsql) != CONNECTION_OK) { /* re-try insert */ + bHadError = tryExec(psz, pData); /* retry */ + if(bHadError || (PQstatus(pData->f_hpgsql) != CONNECTION_OK)) { /* we failed, giving up for now */ reportDBError(pData, 0); closePgSQL(pData); /* free ressources */ @@ -290,6 +323,5 @@ CODESTARTmodInit CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(errmsg, CORE_COMPONENT)); ENDmodInit -/* - * vi:set ai: +/* vi:set ai: */ diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c index 3a79a015..5786e191 100644 --- a/runtime/nsd_gtls.c +++ b/runtime/nsd_gtls.c @@ -82,6 +82,7 @@ static gnutls_certificate_credentials xcred; static gnutls_dh_params dh_params; #ifdef DEBUG +#if 0 /* uncomment, if needed some time again -- DEV Debug only */ /* This defines a log function to be provided to GnuTLS. It hopefully * helps us track down hard to find problems. * rgerhards, 2008-06-20 @@ -90,6 +91,7 @@ static void logFunction(int level, const char *msg) { dbgprintf("GnuTLS log msg, level %d: %s\n", level, msg); } +#endif #endif /* #ifdef DEBUG */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 87dca985..0f4cbce1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,6 @@ TESTRUNS = rt_init rscript check_PROGRAMS = $(TESTRUNS) ourtail nettester tcpflood chkseq -TESTS = $(TESTRUNS) cfg.sh parsertest.sh omod-if-array.sh manytcp.sh +TESTS = $(TESTRUNS) cfg.sh parsertest.sh omod-if-array.sh manytcp.sh diskqueue.sh TESTS_ENVIRONMENT = RSYSLOG_MODDIR='$(abs_top_builddir)'/runtime/.libs/ DISTCLEANFILES=rsyslog.pid test_files = testbench.h runtime-dummy.c @@ -27,6 +27,8 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \ testsuites/omod-if-array.conf \ testsuites/1.omod-if-array \ parsertest.sh \ + diskqueue.sh \ + testsuites/diskqueue.conf \ manytcp.sh \ testsuites/manytcp.conf \ omod-if-array.sh \ diff --git a/tests/diskqueue.sh b/tests/diskqueue.sh new file mode 100755 index 00000000..6384eb64 --- /dev/null +++ b/tests/diskqueue.sh @@ -0,0 +1,31 @@ +# Test for disk-only queue mode +# This test checks if queue files can be correctly written +# and read back, but it does not test the transition from +# memory to disk mode for DA queues. +# added 2009-04-17 by Rgerhards +# This file is part of the rsyslog project, released under GPLv3 +echo testing queue disk-only mode +rm -rf test-spool +mkdir test-spool +rm -f work rsyslog.out.log rsyslog.out.log.save # work files +../tools/rsyslogd -c4 -u2 -n -irsyslog.pid -M../runtime/.libs:../.libs -f$srcdir/testsuites/diskqueue.conf & +sleep 1 +echo "rsyslogd started with pid " `cat rsyslog.pid` +# 20000 messages should be enough - the disk test is slow enough ;) +./tcpflood 127.0.0.1 13514 1 20000 +if [ "$?" -ne "0" ]; then + echo "error during tcpflood! see rsyslog.out.log.save for what was written" + cp rsyslog.out.log rsyslog.out.log.save +fi +sleep 4 # we need this so that rsyslogd can receive all outstanding messages +kill `cat rsyslog.pid` +rm -f work +sort < rsyslog.out.log > work +./chkseq work 0 19999 +if [ "$?" -ne "0" ]; then + # rm -f work rsyslog.out.log + echo "sequence error detected" + exit 1 +fi +rm -f work rsyslog.out.log +rm -rf test-spool diff --git a/tests/tcpflood.c b/tests/tcpflood.c index 9c17fd5b..8dbc201b 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -32,6 +32,7 @@ #include <stdio.h> #include <stdlib.h> #include <time.h> +#include <signal.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> diff --git a/tests/testsuites/diskqueue.conf b/tests/testsuites/diskqueue.conf new file mode 100644 index 00000000..8851a459 --- /dev/null +++ b/tests/testsuites/diskqueue.conf @@ -0,0 +1,16 @@ +# Test for queue disk mode (see .sh file for details) +# rgerhards, 2009-04-17 +$ModLoad ../plugins/imtcp/.libs/imtcp +$MainMsgQueueTimeoutShutdown 10000 +$InputTCPServerRun 13514 + +$ErrorMessagesToStderr off + +# set spool locations and switch queue to disk-only mode +$WorkDirectory test-spool +$MainMsgQueueFilename mainq +$MainMsgQueueType disk + +$template outfmt,"%msg:F,58:2%\n" +$template dynfile,"rsyslog.out.log" # trick to use relative path names! +:msg, contains, "msgnum:" ?dynfile;outfmt diff --git a/tools/msggen.c b/tools/msggen.c index 7990a3c8..06244c18 100644 --- a/tools/msggen.c +++ b/tools/msggen.c @@ -24,7 +24,7 @@ #include <stdio.h> #include <syslog.h> -int main(int argc, char *argv[]) +int main(int __attribute__((unused)) argc, char __attribute__((unused)) *argv[]) { int i; |