Intergrated test scripts with automake
[gnucomo.git] / doc / design.xml
1 <?xml version="1.0"?>
2 <!DOCTYPE doc SYSTEM "/usr/local/xslt/doc.dtd">
3 <?xml-stylesheet type="text/xsl" href="/usr/local/xslt/html.xsl"?>
4 <doc style="main.css">
5
6 <!--
7       XML documentation system
8       Original author :  Arjen Baart - arjen@andromeda.nl
9       Version         : $Revision: 1.7 $
10
11       This document is prepared for XMLDoc. Transform to HTML,
12       LaTeX, Postscript or plain text with XMLDoc utilities and
13       XSLT sheets from http://www.andromeda.nl/projects/xmldoc/
14 -->
15
16 <book>
17 <titlepage>
18    <title>Gnucomo - Computer Monitoring</title>
19    <subtitle>Design description</subtitle>
20    <para><picture src='logo.png' eps='logo' scale='0.7'/></para>
21    <author>Arjen Baart <code>&lt;arjen@andromeda.nl&gt;</code></author>
22    <author>Brenno de Winter<code>&lt;brenno@dewinter.com&gt;</code></author>
23    <author>Peter Roozemaal<code>&lt;mathfox@xs4all.nl&gt;</code></author>
24    <date>November 26, 2003</date>
25    <docinfo>
26       <infoitem label="Version">0.6</infoitem>
27       <infoitem label="Organization">Andromeda Technology &amp; Automation</infoitem>
28       <infoitem label="Organization">De Winter Information Solutions</infoitem>
29    </docinfo>
30    <abstract>
31    </abstract>
32 </titlepage>
33
34 <toc/>
35
36 <chapter>
37 <heading>Introduction</heading>
38
39 <para>
40 <strong>Gnucomo</strong> is a system to monitor computer systems.
41 This document describes the design of the <strong>Gnucomo</strong> applications
42 and is based upon the development manifest.
43 </para>
44
45 </chapter>
46
47 <chapter>
48 <heading>Architecture</heading>
49
50 <para>
51 The systems that are being monitored in <strong>gnucomo</strong> are called
52 <emph>Object</emph>.
53 These may be computers, routers, switches or other active components that
54 are capable of sending reports about their internal workings
55 to the <strong>gnucomo</strong> server.
56 An <emph>Object</emph> plays a central role in the <strong>gnucomo</strong> system.
57 Two separate aspects of an <emph>Object</emph> are monitored: the static state and the
58 dynamic behaviour.
59 The static state of an <emph>Object</emph> is represented by a set of paremeters
60 and the values of these parameter's attributes.
61 The dynamic behaviour of an <emph>Object</emph> is characterized by events that
62 happen on an <emph>Object</emph>.
63 One obvious way to collect a report of these events is to scan the log files of the
64 system and its processes.
65 <emph>Objects</emph> run services and these services are configured with a set
66 of parameters. Also, services produce entries in log files.
67 </para>
68
69 <para>
70 The dataflow architecture of <strong>gnucomo</strong> is shown in the
71 data flow diagram below:
72 </para>
73
74 <para>
75    <picture src='dataflow.png' eps='dataflow' scale='0.7'/>
76 </para>
77
78 <para>
79 At the left of the diagram, information is acquired from the monitored system.
80 Several agents can be used to obtain information from this system, in
81 active or passive ways.
82 A passive agent uses information which is available on the system anyway,
83 such as log files or other lists.
84 An active agent, requests explicit data from the monitored system.
85 One example of a passive agent is <emph>logrunner</emph>, a program which
86 monitors system log files and sends regular updates to the <strong>gnucomo</strong>
87 server.
88 The agents on the monitored system send the data to some kind of transportation channel.
89 This can be any form of transport, such as Email, SOAP, plain file copying or
90 some special network connection.
91 If desired, the transportation may provide security.
92 Once arrived at the server, the information from monitored systems is captured
93 by the <emph>gcm_input</emph> process.
94 This process can obtain the data through many forms of transport and from
95 a number of input formats.
96 <emph>Gcm_input</emph> will try to recognize as much as possible from an
97 input message and store the obtained information into the <emph>Raw Storage</emph>
98 database.
99 The <emph>Raw Storage</emph> data is processed further and analyzed by
100 the <emph>gcm_daemon</emph>, which scans the data, gathers statistics and
101 stores its results into the <emph>Derived Storage</emph> database where
102 it is available for human review and further analysis.
103 </para>
104
105 <para>
106 Architectural items to consider:
107 <itemize>
108 <item>Active and passive data acquisition</item>
109 <item>Monitoring static and dynamic system parameters</item>
110 <item>Upper and lower limits for system parameters</item>
111 </itemize>
112 </para>
113
114 <para>
115 Existing log analysis tools: logwatch, analog.
116 </para>
117 </chapter>
118
119 <chapter>
120 <heading>System design</heading>
121
122 <para>
123 <strong>Gnucomo</strong> is a collection of different application programs,
124 rather than a single application.
125 All these application programs revolve around the <strong>Gnucomo</strong>
126 database as described in the manifest.
127 </para>
128
129 <section>
130 <heading>Database design</heading>
131
132 <para>
133 The design of the database is described extensively in
134 <reference href="manifest.html">the Manifest</reference>.
135 Assuming development is done on the same system on which the real (production)
136 gnucomo database is maintained, there is a need for a separate database
137 on which to perform development and integration tests.
138 Quite often, the test database will need to be destroyed and recreated.
139 To enable testing of <strong>gnucomo</strong> applications, all programs
140 need to access either the test database or the production database.
141 To accommodate this, each application needs an option to override the
142 default name of the <ref to='configuration'>configuration</ref> file (gnucomo.conf).
143 </para>
144
145 <para>
146 To create a convenient programming interface for object oriented languages,
147 a class <emph>gnucomo_database</emph> provides an abstract layer which
148 hides the details of the database implementation.
149 An object of this class maintains the connection to the database server
150 and provides convenience functions for accessing information in the
151 database.
152 A constructor of the <emph>gnucomo_database</emph> is passed a reference to
153 the <emph>gnucomo_configuration</emph> object in order to access the database.
154 This accommodates for both production and test databases.
155 The constructor will immediately try to connect to the database and check its
156 validity.
157 The destructor will of course close the database connection.
158 </para>
159
160 <para>
161 Other methods provide access to the database in a low-level manner.
162 There will be lots more in the future, but here are a few to begin with:
163 <itemize>
164 <item>Send a SQL query to the database.</item>
165 <item>Read a tuple from a result set.</item>
166 <item>Obtain the userid for the current database session.</item>
167 </itemize>
168 </para>
169
170 <para>
171 The information stored in the database as tuples is represented by classes in
172 other programming languages such as C++ of PHP.
173 Each class models a particular type of tuple (an <emph>entity</emph>)
174 in the database.
175 Such classes maintain the relation with the database on one end,
176 while providing methods that are specific to the entity on the other end.
177 All database communication and SQL queries are hidden inside the
178 entity's class.
179 This includes, for example, handling database result sets and access control.
180 </para>
181 <para>
182 Properties and operations that are common to all classes that represent
183 entities in the database are caught in a common base class.
184 The base class, named <emph>database_entity</emph> provides default
185 implementations for loading and storing tuples, construction and destruction
186 and iteration.
187 Most derived classes will override these functions.
188 Two examples of classes that represent entities in the database
189 are <emph>object</emph> and <emph>service</emph>.
190 Both are derived from a <emph>database_entity</emph>, as show below:
191 <para>
192   <picture src='class-database_entity.png' eps='class-database_entity'/>
193 </para>
194 </para>
195
196 <para>
197 Constructors of classes derived from <emph>database_entity</emph> come in
198 two varieties: with or without database interaction.
199 Constructors that do not interact with the database have only one argument:
200 a reference to the <emph>gnucomo_database</emph> object which handles
201 the low-level interaction with the database server.
202 The example below shows a few of these constructors:
203 <verbatim>
204
205   database_entity::database_entity(gnucomo_database &amp;gdb)
206
207   object::object(gnucomo_database &amp;gdb)
208
209   service::service(gnucomo_database &amp;gdb)
210
211 </verbatim>
212 The objective of this type of constructor is to cerate a fresh tuple and
213 store it in the database later on.
214 All these constructors do is establish the connection to the database
215 server and fill in the defaults for the fields in the tuple.
216 A destructor will put the actual tuple into the database if any
217 information in the object has changed.
218 This may be by sending an INSERT if the object is completely fresh
219 or an UPDATE if an already existing tuple was changed.
220 The state information about the freshness of an object is a property
221 common to all database entities and is therefore maintained in
222 the <emph>database_entity</emph> class.
223 </para>
224 <para>
225 Constructors that do interact with the database accept additional
226 arguments after the initial <emph>gnucomo_database</emph> reference.
227 These extra arguments are used to retrieve a tuple from the database.
228 Examples of such constructors are:
229 <verbatim>
230
231    object::object(gnucomo_database &amp;gdb, String hostname)
232
233    object::object(gnucomo_database &amp;gdb, long long oid)
234
235    service::service(gnucomo_database &amp;gdb, String name)
236
237 </verbatim>
238 The set of arguments must of course correspond to a set of fields that
239 uniquely identify the tuple.
240 The primary key of the database table would be ideally suitable.
241 If the tuple is not found in the database, data members of the object
242 are set to default values and the object is marked as being fresh and
243 not changed.
244 </para>
245
246 <para>
247 Methods with the same name as a field in a tuple read or change the
248 value of that field.
249 Without an argument, such a method returns the current value of the field.
250 With a single argument, the field is set to the new value passed in the
251 argument and the method returns the original value.
252 Whenever a field is set to a new value, the object is marked as being
253 'changed'.
254 A destructor will then save the tuple to the database.
255 </para>
256 </section>
257
258 <section>
259 <heading><label name='configuration'/>Configuration</heading>
260
261 <para>
262 Configuration parameters are stored in a XML formatted configuration file.
263 The config file contains a two-level hierarchy.
264 The first level denotes the section for which the parameter is used
265 and the second level is the parameter itself.
266 Both sections and parameters are elements in XML terminology.
267 The top-level (root) element is the configuration tree itself.
268 The root element must have the same name as the application's name
269 for which the configuration is intended.
270 The level-1 elements are sections of the configuration tree.
271 Within these section elements, the configuration has several parameter elements.
272 Each parameter is an element by itself.
273 The element's name is the name of the parameter, just as a section
274 element's name is the name of the section.
275 The content of the parameter element is the value of the parameter.
276 Attributes in either section elements or parameter elements are not used.
277 </para>
278 <para>
279 The configuration file is located in two places.
280 The is a system wide configuration in
281 <code>/usr/local/etc/gnucomo.conf</code> and each user may
282 have his or her own configuration in <code>~/.gnucomo.conf</code>.
283 The value of a user-specific configuration parameter overrides
284 the system-wide value.
285 </para>
286 <para>
287 The following sections and parameters are defined for the Gnucomo
288 configuration:
289 <itemize>
290 <item>database
291    <itemize>
292    <item>type</item>
293    <item>name</item>
294    <item>user</item>
295    <item>password</item>
296    <item>host</item>
297    <item>port</item>
298    </itemize>
299 </item>
300 <item>logging
301    <itemize>
302    <item>method</item>
303    <item>destination</item>
304    <item>level</item>
305    </itemize>
306 </item>
307 <item>gcm_input
308    <itemize>
309    <item>dbuser</item>
310    <item>password</item>
311    </itemize>
312 </item>
313 <item>gcm_daemon
314    <itemize>
315    <item>dbuser</item>
316    <item>password</item>
317    </itemize>
318 </item>
319 </itemize>
320
321 The <emph>database</emph> section defines how the database is accessed.
322 The <emph>database/type</emph> parameter must have the content <code>PostgreSQL</code>.
323 Other database systems are not supported yet.
324 The <emph>database/user</emph> and <emph>database/password</emph> provide default
325 login information onto the database server.
326 Specific user names and passwords may be specified for separate applications, such
327 as <emph>gcm_input</emph> and <emph>gcm_daemon</emph>.
328 </para>
329
330 <subsection>
331 <heading>gnucomo_config class</heading>
332
333 <para>
334 Each Gnucomo application should have exactly one object of the
335 <strong>gnucomo_config</strong> to obtain its configuration
336 parameters.
337 The following methods are supported in this class:
338
339 <itemize>
340
341 <item>
342   read(String name)
343   <para>
344   Reads the XML formatted configuration files from
345   <code>/usr/local/etc/&lt;name&gt;.conf</code> and
346   <code>~/.&lt;name&gt;.conf</code>.
347   </para>
348 </item>
349
350 <item>
351   String find_parameter(String section, String param)
352   <para>
353   Return the value of the parameter <emph>param</emph> in
354   section <emph>section</emph>.
355   </para>
356 </item>
357
358 <item>
359   String Database()
360   <para>
361   Return the database access string to be used for the PgDatabase constructor.
362   </para>
363 </item>
364
365 </itemize>
366 </para>
367
368 </subsection>
369 </section>
370
371 <section>
372 <heading>gcm_input</heading>
373
374 <para>
375 <strong>gcm_input</strong> is the application which captures messages from client
376 systems in one form or another and tries to store information from these messages
377 into the database.
378 A client message may arrive in a number of forms and through any kind of
379 transportation channel.
380 Here are a few examples:
381
382 <itemize>
383 <item>Obtained directly from a local client's file system.</item>
384 <item>From the output of another process, through standard input.</item>
385 <item>Copied remotely from a client's file system, e.g. using
386    <code>ftp</code>, <code>rcp</code> or <code>scp</code>.
387    This is usually handled through spooled files.
388 </item>
389 <item>Through an email.</item>
390 <item>As a SOAP web service, carried through HTTP or SMTP.</item>
391 <item>Through a TCP connection on a special socket.</item>
392 </itemize>
393
394 On top of that, any message may be encrypted, for example with PGP or GnuPG.
395 In any of these situations, <strong>gcm_input</strong> should be able to extract
396 as much information as possible from the client's message.
397 In case the message is encrypted, it may not be possible to run <strong>gcm_input</strong>
398 in the background, since human intervention is needed to enter the secret key.
399 </para>
400 <para>
401 The primary function of <strong>gcm_input</strong> is to store lines from a client's
402 log files into the <emph>log</emph> table or scan a report from a probe and update
403 the <emph>parameter</emph> table.
404 To do this, we need certain information about the client message that is usually not
405 in the content of a log file.
406 This information includes:
407 <itemize>
408 <item>The source of the log file, most often in the form of the client's hostname.</item>
409 <item>The time stamp of the time on which the log file arrived on the server.</item>
410 <item>The service on the client which produced the log file.</item>
411 </itemize>
412
413 Sometimes, this information is available from the message itself, as in an email header.
414 On other occasions, the information needs to be supplied externally,
415 e.g. by using command line options.
416 In any case, this type of 'header' information is relevant to the message
417 as a whole.
418 As a result, <emph>gcm_input</emph> can accept one and only one message at a time.
419 For example, it is not possible to connect the standard output of
420 <emph>logrunner</emph> to the standard input of <emph>gcm_input</emph> and have
421 a continuous stream of messages from different log sources.
422 Each message should be fed to <emph>gcm_input</emph> separately.
423 Also when <emph>logrunner</emph> uses a special socket to send logging data,
424 a new connection must be created for each message.
425 The dataflow diagram below shows how a message travels from the input source
426 to the database.
427 </para>
428
429 <para>
430    <picture src='gcm_input-dataflow.png' eps='gcm_input-dataflow' scale='0.6'/>
431 </para>
432
433 <para>
434 Internally, <emph>gcm_input</emph> handles <ref to='XML_input'>XML input</ref>
435 and each input item must have its data fields split into appropriate XML elements.
436 When data is offered in some other form, this data must be filtered
437 and transformed into XML before <emph>gcm_input</emph> can handle it.
438 Two levels of transformation are possible.
439 At the highest level, the whole message is transformed into an XML
440 document with a <code>&lt;message&gt;</code> root element and the
441 appropriate <code>&lt;header&gt;</code> and <code>&lt;data&gt;</code>
442 elements, all of which are put in the proper namespace.
443 At the lowest level, each line of the message's data can be transformed
444 into a <code>&lt;cooked&gt; &lt;log&gt;</code> element.
445 Two classes of replaceable filter objects take care of these transformations.
446 Depending on the content of the message and/or command line options to
447 <emph>gcm_input</emph>, an appropriate filter object is inserted into
448 the data stream.
449 </para>
450
451 <para>
452 The <ref to='message_filter'><emph>message_filter</emph></ref> transforms
453 the raw input data into an XML document.
454 The XML document is processed by the XML parser and stored into the database
455 or saved into a spool area for later processing.
456 The latter happens, for example, when the database is unavailable.
457 The task of the <emph>message_filter</emph> object is to create the &lt;header&gt;
458 elements and the &lt;data&gt; element containing either a &lt;log&gt; or
459 a &lt;parameters&gt; element, along with all their child elements.
460 To do this, a <emph>message_filter</emph> object must work closely
461 together with a <emph>line_cooker</emph> object.
462 </para>
463 <para>
464 There are two major classes of <emph>message_filter</emph> objects:
465 one to create a &lt;log&gt; element and one to create a &lt;parameters&gt;
466 element.
467 Either one of these must be capable to create a &lt;header&gt; element which
468 is filled with information from command line arguments or an email header
469 in the input stream.
470 The base <emph>message_filter</emph> is not much more than a short circuit,
471 which merely copies the input stream into the internal XML buffer.
472 This is used when the input is already in XML format.
473 </para>
474
475 <para>
476 The <ref to='line_cooker'><emph>line_cooker</emph></ref>
477 operates on a node in the DOM tree which is
478 supposed to be a &lt;raw&gt; &lt;log&gt; element that contains one line
479 from a log file.
480 The <emph>line_cooker</emph> transforms a <emph>raw</emph> log line into
481 its constituent parts that make up en &lt;cooked&gt; element.
482 Since each type of log file uses a different layout and syntax,
483 different line cookers can be used, depending on the type of log.
484 This type is indicated by the &lt;messagetype&gt; element in the header
485 part of the message.
486 Clearly, the <emph>line_cooker</emph> is a polymorphic entity.
487 Exactly which <emph>line_cooker</emph> is used is determined through
488 <ref to='classifying'>classifying</ref>
489 the content of the message or the message type indicated in the header.
490 The <emph>line_cooker</emph> base class provides a default implementation
491 for most methods, while derived classes provide the actual cooking.
492 </para>
493
494 <para>
495 Output created by <emph>gcm_input</emph> for logging and debugging purposes
496 can be sent to one of several destinations:
497 <itemize>
498 <item>standard error.</item>
499 <item>a log file.</item>
500 <item>the system log.</item>
501 <item>an email address.</item>
502 </itemize>
503 The actual destination is stated in the <strong>gnucomo</strong>
504 configuration file. The default is stderr.
505 A <emph>log</emph> object filters output according to the debug level.
506 </para>
507
508 <subsection>
509 <heading><label name='classifying'/>Classifying messages</heading>
510
511 <para>
512 Apart from determining information about the client's message, the content
513 of the message needs to be analyzed in order to handle it properly.
514 The body of the message may contain all sorts of information, such as:
515 <itemize>
516 <item>System log file</item>
517 <item>Apache log file</item>
518 <item>Report from a Gnucomo agent or other probe, for example "rpm -qa"
519       or "df -k".</item>
520 <item>Generic XML input</item>
521 <item>Something else...</item>
522 </itemize>
523
524 Basically, <strong>gcm_input</strong> accepts two kinds of input: Log lines
525 and parameter reports.
526 The message is analyzed to obtain information about what the message entails
527 and where it came from.
528 The message classification embodies the way in which a message must be
529 handled and in what way information from the message can be put into
530 the database.
531 Aspects for handling the message are for example:
532 <itemize>
533 <item>Strip lines at the beginning or end.</item>
534 <item>Store each line separately or store the message as a whole.</item>
535 <item>How to extract hostname, arrival time and service from the message.</item>
536 <item>How to break up the message into individual fields for a <emph>log</emph> record.</item>
537 </itemize>
538 These aspects are all handled in polymorphic <emph>message_filter</emph>
539 and <emph>line_cooker</emph> classes.
540 The result of classifying a message is the selection of the proper
541 objects derived from these classes from a collection of such objects.
542 </para>
543
544 <para>
545 The <strong>classify()</strong> method tries to extract that information.
546 Sometimes, this information can not be determined with absolute 100% certainty.
547 The certainty expresses how sure we are about the contents in the message.
548 Classifying a message may be performed with an algorithm as shown in
549 the following pseudo code:
550
551 <verbatim>
552 uncertainty = 1.0
553
554 while uncertainty &gt; &epsilon; AND not at end
555
556    Scan for a marker
557
558    if a marker matches
559
560       uncertainty = uncertainty * P    //  P &lt; 1.0
561 </verbatim>
562
563 With <emph>uncertainty</emph> of course being the opposite of the certainty.
564 It expresses how unsure we are about the content of the message, as a
565 number between 0.0 and 1.0.
566 In fact, it is the probability that the message is not what we think it is.
567 Initially, a message is not classified and the uncertainty is 1.0.
568 Some lines point toward a certain type of message but do not absolutely determine
569 the type of a message. Other pieces of text are typical for a certain message type.
570 Such pieces of text, called <emph>markers</emph> are discovered in a message,
571 possibly by using regular expression matches.
572 Examples of markers that determine the classification of a client message
573 are discussed below.
574 </para>
575
576 <para>
577 To determine the message type, <strong>classify()</strong> uses the collection
578 of <ref to='line_cooker'><emph>line_cooker</emph></ref> objects and maintains
579 the uncertainty associated with each <emph>line_cooker</emph> object.
580 A line of input from the message is tested using the <emph>line_cooker::check_pattern</emph>
581 method for each <emph>line_cooker</emph>object.
582 When a marker matches, we are a bit more sure about the content of the message
583 and the uncertainty for that <emph>line_cooker</emph> object decreases by
584 multiplying the uncertainty by <strong>P</strong>, a number between 0 and 1.
585 This process continues line after line from the input message until the
586 uncertainty for one of the <emph>line_cooker</emph> objects is sufficiently low
587 (i.e. less than a preset threshold, &epsilon;).
588 At the end, the <emph>line_cooker</emph> object with the lowest uncertainty
589 is selected.
590
591 <verbatim>
592 From - Sat Sep 14 15:01:15 2002
593 </verbatim>
594
595 This is almost certainly a UNIX style mail header.
596 There should be lines beginning with <code>From:</code> and <code>Date:</code>
597 before the first empty line is encountered.
598 The hostname of the client that sent the message and the time of arrival
599 can be determined from these email header lines.
600 The content of the message is still to be determined by matching
601 other markers.
602
603 <verbatim>
604 -----BEGIN PGP MESSAGE-----
605 </verbatim>
606
607 Such a line in the message certainly means that the message is PGP or GnuPG
608 encrypted.
609 Decrypting is possible only if someone or something provides a secret key.
610
611 <verbatim>
612 &lt;?xml version='1.0'?&gt;
613 </verbatim>
614
615 The XML header declares the message to be generic XML input.
616 The structure of the XML message that <strong>gcm_input</strong> accepts
617 is described in the next section.
618
619 <verbatim>
620 Sep  1 04:20:00 kithira kernel: solo1: unloading
621 </verbatim>
622
623 The general pattern of a system log file is an abbreviated month name, a day,
624 a time, a name of a host without the domain, the name of a service followed
625 by a colon and finally, the message of that service.
626 We can match this with a regular expression to see if the message holds syslog lines.
627 Similar matches can be used to find Apache log lines or output from the <emph>dump</emph>
628 backup program or anything else.
629 </para>
630 </subsection>
631
632 <subsection>
633 <heading><label name='XML_input'/>Generic XML input</heading>
634
635 <para>
636
637 Since <strong>gcm_input</strong> can not understand every conceivable form
638 of input, a client can offer its input in a more generic form which reflects
639 the structure of the Gnucomo database.
640 In this case, the input is structured in an XML document that contains the input
641 data in a form that allows <strong>gcm_input</strong> to store the information
642 into the database without knowing the nature of the input.
643 The XML root element for <strong>gcm_input</strong> is a <emph>&lt;message&gt;</emph>, defined
644 in the namespace with namespace name <code>http://gnucomo.org/transport/</code>.
645 All other elements and attributes of the <emph>&lt;message&gt;</emph> must be defined
646 within this namespace.
647 </para>
648 <para>
649 Within the <emph>&lt;message&gt;</emph> element there is a <emph>&lt;header&gt;</emph>
650 and a <emph>&lt;data&gt;</emph> element.
651 The <emph>&lt;data&gt;</emph> element may contain the log data in an externally
652 specified format.
653 The <emph>&lt;header&gt;</emph> element contains a number of elements (fields), some
654 mandatory, some optional. The text of the element contains the value of
655 the element.
656 The following elements have been defined:
657
658 <itemize>
659 <item>
660 <emph>&lt;mesagetype&gt;</emph> mandatory
661      <para>
662       The type (format) of the log data in the data element. The message type
663       determines the way in which raw log elements are parsed and split up
664       into separate fields for insertion into the database.
665       The message types gcm_input understands are:
666       <itemize>
667       <item><code>system log</code> : The most common form of UNIX system logs.
668             Also used in most Linux distributions.
669       </item>
670       <item><code>IRIX system log</code> : Variation of system log, used by SGI.
671       </item>
672       <item><code>apache access log</code> : Access log of the Apache http daemon,
673             in default form.
674       </item>
675       <item><code>apache error log</code> : Error log of the Apache http daemon,
676             in default form.
677       </item>
678       </itemize>
679       There must also be a 'generic' system log in case all elements are
680       cooked already.
681      </para>
682 </item>
683 <item>
684 <emph>&lt;hostname&gt;</emph> mandatory
685      <para>
686       The name of the system that generated the data in the data block.
687       This can be different from the computer composing the message.
688      </para>
689 </item>
690 <item>
691 <emph>&lt;service&gt;</emph> optional
692      <para>
693       The (default) value of the service running on the host that
694       generated the message data. For log files that don't contain the
695       service name embedded in them.
696      </para>
697 </item>
698 <item>
699 <emph>&lt;time&gt;</emph> optional
700      <para>
701       The best approximation to the time that the data was generated.
702       For (log)data that doesn't contain an embedded date stamp.
703      </para>
704 </item>
705 </itemize>
706
707 The following example shows an XML message for <strong>gcm_input</strong>
708 with a filled-in header and an empty <emph>&lt;data&gt;</emph> element:
709
710 <verbatim>
711   &lt;gcmt:message xmlns:gcmt='http://gnucomo.org/transport/'&gt;
712      &lt;gcmt:header&gt;
713         &lt;gcmt:messagetype&gt;apache error log&lt;/gcmt:messagetype&gt;
714         &lt;gcmt:hostname&gt;client.gnucomo.org&lt;/gcmt:hostname&gt;
715         &lt;gcmt:service&gt;httpd&lt;/gcmt:service&gt;
716         &lt;gcmt:time&gt;2003-04-17 14:40:46.312895+01:00&lt;/gcmt:time&gt;
717      &lt;/gcmt:header&gt;
718      &lt;gcmt:data/&gt;
719   &lt;/gcmt:message&gt;
720 </verbatim>
721 </para>
722
723 <para>
724 The <emph>data</emph> element can hold one of two possible child
725 elements: <emph>&lt;log&gt;</emph> or <emph>&lt;parameters&gt;</emph>.
726 The <emph>&lt;log&gt;</emph> element may contain any number of lines from
727 a system's log file, each line in a separate element.
728 A single log line is the content of either a <emph>&lt;raw&gt;</emph> or
729 a <emph>&lt;cooked&gt;</emph> element.
730 The <emph>&lt;raw&gt;</emph> element contains the log line "as is" and nothing more.
731 This is the easiest way to provide XML data for <strong>gcm_input</strong>.
732 However, the log line itself must be in a form that <strong>gcm_input</strong>
733 can understand.
734 After all, <strong>gcm_input</strong> still needs to extract meaningful information
735 from that line, such as the time stamp and the service that created the log.
736 The client can also choose to provide that information separately by encapsulating
737 the log line in a <emph>&lt;cooked&gt;</emph> element.
738 This element may have up to four child elements, two of which are mandatory:
739 <itemize>
740 <item><emph>&lt;timestamp&gt;</emph> mandatory.
741    <para>
742    The time at which the log line was generated by the client.
743    </para>
744 </item>
745 <item><emph>&lt;hostname&gt;</emph> optional.
746    <para>
747    For logs that include a hostname in each line. This hostname is checked
748    against the hostname in the <emph>&lt;header&gt;</emph> element.
749    </para>
750 </item>
751 <item><emph>&lt;service&gt;</emph> optional.
752    <para>
753    If the service that generated the log is not provided in the <emph>&lt;header&gt;</emph>
754    the service must be stated for each log line separately.
755    Otherwise, each log line is assumed to be generated by the same service.
756    </para>
757 </item>
758 <item><emph>&lt;raw&gt;</emph> mandatory.
759    <para>
760    The content of the full log line. This would have the same content of the singular
761    <emph>&lt;raw&gt;</emph> element if the log line was not provided in a
762    <emph>&lt;cooked&gt;</emph> element.
763    </para>
764 </item>
765 </itemize>
766 The following shows an example of the log message with two lines in the
767 <emph>&lt;log&gt;</emph> element, one raw and one cooked:
768
769 <verbatim>
770   &lt;gcmt:data xmlns:gcmt='http://gnucomo.org/transport/'&gt;
771     &lt;gcmt:log&gt;
772      &lt;gcmt:raw&gt;
773        Apr 13 04:31:03 schiza kernel: attempt to access beyond end of device
774      &lt;/gcmt:raw&gt;
775      &lt;gcmt:cooked&gt;
776         &lt;gcmt:timestamp&gt;2003-04-13 04:31:03+02:00&lt;/gcmt:timestamp&gt;
777         &lt;gcmt:hostname&gt;schiza&lt;/gcmt:hostname&gt;
778         &lt;gcmt:service&gt;kernel&lt;/gcmt:service&gt;
779         &lt;gcmt:raw&gt;
780          Apr 13 04:31:03 schiza kernel: 03:05: rw=0, want=1061109568, limit=2522173
781         &lt;/gcmt:raw&gt;
782      &lt;/gcmt:cooked&gt;
783     &lt;/gcmt:log&gt;
784   &lt;/gcmt:data&gt;
785 </verbatim>
786 </para>
787
788 <para>
789 The <emph>&lt;parameters&gt;</emph> element contains a list of parameters
790 of the same class. The class is provided as an attribute in the
791 <emph>&lt;parameters&gt;</emph> open tag.
792 There is a <emph>&lt;parameter&gt;</emph> element for each parameter in the list.
793 The child elements of a <emph>&lt;parameter&gt;</emph> are one optional
794 <emph>&lt;description&gt;</emph> element and zero or more <emph>&lt;property&gt;</emph>
795 elements.
796 The names of a parameter and a property are provided by the mandatory <emph>name</emph>
797 attributes in the respective elements.
798 The following example shows a possible parameter report from a "df -k":
799 <verbatim>
800   &lt;gcmt:data xmlns:gcmt='http://gnucomo.org/transport/'&gt;
801     &lt;gcmt:parameters gcmt:class='filesystem'&gt;
802       &lt;gcmt:parameter gcmt:name='root'&gt;
803          &lt;gcmt:description&gt;Root filesystem&lt;/gcmt:description&gt;
804          &lt;gcmt:property gcmt:name='size'&gt;303344&lt;/gcmt:property&gt;
805          &lt;gcmt:property gcmt:name='used'&gt;104051&lt;/gcmt:property&gt;
806          &lt;gcmt:property gcmt:name='available'&gt;183632&lt;/gcmt:property&gt;
807          &lt;gcmt:property gcmt:name='device'&gt;/dev/hda1&lt;/gcmt:property&gt;
808          &lt;gcmt:property gcmt:name='mountpoint'&gt;/&lt;/gcmt:property&gt;
809       &lt;/gcmt:parameter&gt;
810       &lt;gcmt:parameter gcmt:name='usr'&gt;
811          &lt;gcmt:description&gt;Usr filesystem&lt;/gcmt:description&gt;
812          &lt;gcmt:property gcmt:name='size'&gt;5044188&lt;/gcmt:property&gt;
813          &lt;gcmt:property gcmt:name='used'&gt;3073716&lt;/gcmt:property&gt;
814          &lt;gcmt:property gcmt:name='available'&gt;1714236&lt;/gcmt:property&gt;
815          &lt;gcmt:property gcmt:name='device'&gt;/dev/hdd2&lt;/gcmt:property&gt;
816          &lt;gcmt:property gcmt:name='mountpoint'&gt;/usr&lt;/gcmt:property&gt;
817       &lt;/gcmt:parameter&gt;
818     &lt;/gcmt:parameters&gt;
819   &lt;/gcmt:data&gt;
820 </verbatim>
821 </para>
822
823 </subsection>
824
825 <subsection>
826 <heading>Gcm_input classes</heading>
827 <para>
828 The figure below shows the class diagram that is used for <strong>gcm_input</strong>:
829    <para>
830    <picture src='classes-gcm_input.png' eps='classes-gcm_input' scale='0.8'/>
831    </para>
832
833 The heart of the application is a <emph>client_message</emph> object.
834 This object reads the message through the
835 <ref to='message_buffer'><emph>message_buffer</emph></ref> from some
836 input stream (file, string, stdin or socket), classifies the message and
837 enters information from the message into the database.
838 The <emph>client_message</emph> object holds a collection of <emph>message_filter</emph>
839 and associated <emph>line_cooker</emph> objects.
840 The association is maintained in a <emph>xform</emph> object.
841 Note that several <emph>line_cooker</emph> can be associated with
842 with a single <emph>message_filter</emph> object.
843 For example, a system log or a web server log are processed in a similar
844 manner, i.e. each line is transformed into a &lt;log&gt; element.
845 The patterns of the individual lines, however are entirely different.
846 During the classification of the input data, one combination of a
847 <emph>message_filter</emph> and <emph>line_cooker</emph> is selected.
848 The classification process works by calculating the uncertainty with which
849 a <emph>line_cooker</emph> matches with the input data.
850 The one with the least uncertainty is selected.
851 </para>
852
853 <subsubsection>
854 <heading><label name='client_message'/>client_message</heading>
855 <para>
856 The <emph>client_message</emph> has a relationship with a <emph>gnucomo_database</emph> object which
857 is an abstraction of the tables in the database.
858 These are the methods for the <emph>client_message</emph> class:
859
860 <itemize>
861 <item><code>client_message::client_message(istream *in, gnucomo_database *db)</code>
862    <para>
863    Constructor.
864    </para>
865 </item>
866 <item><code>void add_cooker(line_cooker *lc, message_filter *mf)</code>
867   <para>
868   Add another <emph>line_cooker</emph> object with the associated
869   <emph>message_filter</emph> object to the collection.
870   This initializes the uncertainty with which the <emph>line_cooker</emph>
871   is selected to 1.0.
872   </para>
873 </item>
874 <item><code>double client_message::classify(String host, date arrival_d,
875                                              hour arrival_t, String serv)</code>
876   <para>
877   Try to classify the message and return the certainty with which the class of the
878   message could be determined.
879   If the hostname, arrival time and service can not be extracted from the message,
880   use the arguments as default.
881   This will examine the first few lines of the input data
882   to select one of the <emph>message_filter</emph> with
883   associated <emph>line_cooker</emph> objects
884   from the collection built with the <emph>add_cooker</emph> method.
885   </para>
886 </item>
887 <item><code>int enter()</code>
888   <para>
889   Insert the message contents into the gnucomo database.
890   Returns the number of records inserted.
891   The input data from the <emph>message_buffer</emph>
892   is first transformed into an XML document (a strstream object)
893   by invoking the <emph>message_filter</emph> and <emph>line_cooker</emph> objects.
894   The XML document in the internal buffer is then parsed into an
895   XML DOM tree, using the Gnome XML parser.
896   The XML document may also be validated against an XML Schema definition.
897   </para>
898   <para>
899   After extracting and checking the &lt;header&gt; elements,
900   the data nodes are extracted and inserted into the database,
901   possibly using a <emph>line_cooker</emph> object to cook raw
902   log elements.
903   If an error occurs in some stage of this process, the XML document
904   is dumped in a spool area for later processing.
905   </para>
906 </item>
907 </itemize>
908
909 </para>
910 </subsubsection>
911
912 <subsubsection>
913 <heading><label name='message_filter'/>message_filter</heading>
914 <para>
915 A <emph>message_filter</emph> transforms the raw input data into an
916 XML document suitable for further parsing and storage into the database.
917 The base class, <emph>message_filter</emph> does nothing but copy the
918 input stream into an internal XML buffer.
919 An object of this class is used when the input is already in XML format.
920 Classes derived from <emph>message_filter</emph> read the input line by line,
921 possibly extracting information from an email header if available.
922 <itemize>
923 <item>
924    <code>message_filter::contruct_XML(message_buffer &amp;in, strstream &amp;xml)</code>
925    <para>
926    Simply copy the input stream into the internal XML buffer.
927    The base class function is used when the input is already in XML format.
928    Derived classes will override this function.
929    </para>
930 </item>
931 </itemize>
932 </para>
933
934 <para>
935 Classes derived from <emph>message_filter</emph> transform various kinds
936 of input into an XML document. The following diagram shows some examples:
937
938    <para>
939    <picture src='classes-message_filter.png' eps='classes-message_filter' scale='0.8'/>
940    </para>
941
942 The two classes, derived directly from <emph>message_filter</emph> reflect
943 that <strong>gcm_input</strong> can handle two kinds of input: The
944 <emph>log_filter</emph> for log files
945 and <emph>parameters_filter</emph> for parameter reports.
946 Each of these types of input are transformed into entirely different XML
947 documents and are stored quite differently into the database.
948 Classes that are derived further down the hierarchy will handle more specific
949 forms of input.
950 </para>
951 </subsubsection>
952
953 <subsubsection>
954 <heading><label name='line_cooker'/>line_cooker</heading>
955 <para>
956 To turn a raw line from a log file onto separate parts that can be stored
957 in the database, i.e. parse the line, the <emph>client_message</emph>
958 object uses a <emph>line_cooker</emph> object.
959 This is a polymorphic object, so each type of log can have its own parser,
960 while the <emph>client_message</emph> object uses a common interface
961 for each one.
962 For each message, one specific <emph>line_cooker</emph> object is
963 selected as determined by the message type.
964 E.g., the derived class <emph>syslog_cooker</emph> is used for system logs.
965 When the <emph>client_message</emph> object encounters a <strong>raw</strong>
966 log element, it takes the following steps to turn this into a
967 <strong>cooked</strong> log element:
968 <enumerate>
969 <item>
970   Remove the TEXT node of the "raw" element and save its content.
971 </item>
972 <item>
973   Change the name of the element into "cooked".
974 </item>
975 <item>
976   Check if the content matches the syntax of the type of log we're
977   processing at the moment.
978   This depends on the message type and is therefore a task for the
979   <emph>line_cooker</emph> object.
980 </item>
981 <item>
982   Have the <emph>line_cooker</emph> parse the content and extract
983   the time stamp and optionally the hostname and service.
984 </item>
985 <item>
986   Insert new child elements into the cooked element.
987 </item>
988 </enumerate>
989 After that, the <emph>cooked</emph> element is ready for further processing
990 and possibly storing into the database.
991 </para>
992
993 <para>
994 The <emph>line_cooker</emph> base class holds three protected members
995 that must be filled with information by the derived classes:
996 <itemize>
997 <item><code>UTC ts</code> : the timestamp.</item>
998 <item><code>String hn</code> : the hostname</item>
999 <item><code>String srv</code> : the service</item>
1000 </itemize>
1001 Corresponding base class methods (<emph>timestamp</emph>,
1002 <emph>hostname</emph> and <emph>service</emph>) will do
1003 nothing more than return these values.
1004 It is up to the derived class's <emph>cook_this</emph> method
1005 to properly initialize these members.
1006 </para>
1007
1008 <para>
1009 The methods for the <emph>line_cooker</emph> class are:
1010 <itemize>
1011 <item>
1012   <code>bool line_cooker::check_pattern(String logline)</code>
1013   <para>
1014   Tries to match the <emph>logline</emph> against that patterns
1015   that describe the message syntax.
1016   In the <emph>line_cooker</emph> base class, this is a pure virtual function.
1017   Returns true if the log line adheres to the message-specific syntax.
1018   </para>
1019 </item>
1020 <item>
1021   <code>bool line_cooker::cook_this(String logline, UTC arrival)</code>
1022   <para>
1023   Extracts information from the <emph>logline</emph>.
1024   The <emph>arrival</emph> can be used to make corrections to incomplete
1025   time stamps in the log file.
1026   The implementation in a derived class must properly initialize the protected
1027   members described above.
1028   In the <emph>line_cooker</emph> base class, this is a pure virtual function.
1029   Returns false if the pattern does not match.
1030   </para>
1031 </item>
1032 <item>
1033   <code>String line_cooker::message_type()</code>
1034   <para>
1035   Return the message type for which this line cooker is intended.
1036   </para>
1037 </item>
1038 <item>
1039   <code>UTC line_cooker::timestamp()</code>
1040   <para>
1041   Returns the timestamp that was previously extracted from the log line
1042   or a 'null' timestamp if that information could nnot be extracted.
1043   </para>
1044 </item>
1045 <item>
1046    <code>String line_cooker::hostname()</code>
1047   <para>
1048   Returns the hostname that was previously extracted from the log line,
1049   or an empty string if that information could not be extracted.
1050   </para>
1051 </item>
1052 <item>
1053    <code>String line_cooker::service()</code>
1054   <para>
1055   Returns the service that was previously extracted from the log line,
1056   or an empty string if that information could not be extracted.
1057   </para>
1058 </item>
1059 </itemize>
1060 </para>
1061 </subsubsection>
1062
1063 <subsubsection>
1064 <heading><label name='message_buffer'/>message_buffer</heading>
1065 <para>
1066 Some kind of input buffering is needed when a client message is being processed.
1067 The contents of the message are not entirely clear until a few lines are analyzed,
1068 and these lines probably need to be read again.
1069 When the message is stored in a file, this is no problem; a simple lseek allows us
1070 to read any line over and over again.
1071 However, when the message comes from an input stream, like a TCP socket or just
1072 plain old stdin, this is a different matter.
1073 Lines of the messages that are already read will be lost forever, unless they are
1074 stored somewhere.
1075 To store an input stream temporarily, there are two options:
1076 <enumerate>
1077 <item>In an internal memory buffer.</item>
1078 <item>In an external (temporary) file.</item>
1079 </enumerate>
1080 The <emph>message_buffer</emph> class takes care of the input buffering, thus
1081 hiding these implementation details.
1082 On the outside, a <emph>message_buffer</emph> can be read line by line until the
1083 end of the input is reached.
1084 Lines of input can be read again by backing up to the beginning of the message
1085 by using the <strong>rewind()</strong> method or by backing up one line
1086 with the <strong>--</strong> operator.
1087 The <emph>message_buffer</emph> object maintains a pointer to the next
1088 available line.
1089 The <strong>++</strong> operator, being the opposite of the <strong>--</strong>
1090 operator, skips one line.
1091 </para>
1092
1093 <para>
1094 The <strong>&gt;&gt;</strong> operator reads data from the message
1095 into the second (String) operand, just like the <strong>&gt;&gt;</strong>
1096 operator for an istream.
1097 There is a small difference, though.
1098 The <strong>&gt;&gt;</strong> operator for a <emph>message_buffer</emph>
1099 returns a boolean value which states if there actually was input available.
1100 This value will usually turn to <code>false</code> at the end of file.
1101 A second difference is the fact that input data can only be read into
1102 <emph>String</emph> objects a line at a time.
1103 There are no functions for reading integer or floating point numbers.
1104 The <strong>&gt;&gt;</strong> operator reads the next line either from
1105 an internal buffer or from the external input stream if the internal
1106 buffer is exhausted.
1107 Lines read from the input stream are cached in the internal buffer,
1108 so they are available for reading another time, e.g. after
1109 rewinding to the beginning of the message.
1110 </para>
1111
1112 <para>
1113 Methods for the <emph>message_buffer</emph> class:
1114
1115 <itemize>
1116 <item>message_buffer::message_buffer(istream *in)
1117   <para>
1118   Constructor.
1119   </para>
1120 </item>
1121 <item>bool operator &gt;&gt;(message_buffer &amp;, String &amp;)
1122 </item>
1123 <item>message_buffer::rewind()</item>
1124 <item>message_buffer::operator --</item>
1125 <item>message_buffer::operator ++</item>
1126 </itemize>
1127 </para>
1128
1129 </subsubsection>
1130 </subsection>
1131
1132 <subsection>
1133
1134 <heading>Command arguments</heading>
1135
1136 <para>
1137 <strong>Gcm_input</strong> understands the following command line arguments:
1138 <itemize>
1139 <item>-c &lt;name&gt; : Configuration name</item>
1140 <item>-d &lt;date&gt; : Arrival time of the message</item>
1141 <item>-h &lt;hostname&gt; : FQDN of the client</item>
1142 <item>-s &lt;service&gt; : service that created the log</item>
1143 <item>-v : verbose output. Print lots of debug information</item>
1144 <item>-V : Print version and exit</item>
1145 </itemize>
1146 </para>
1147 </subsection>
1148 </section>
1149
1150 <section>
1151 <heading>gcm_daemon</heading>
1152 <para>
1153 <strong>Gcm_daemon</strong> is the application that processes data just
1154 arrived in the database.
1155 It handles the log-information delivered by <strong>gcm_input</strong>
1156 in the <emph>log</emph> table of the database.
1157 With the data further storage and classification can be done.
1158 Where <strong>gcm_input</strong> is a highly versatile application that is
1159 loaded and ended all the time the daemon is continuously available monitoring
1160 the entire system. Basically the daemon monitors everything that happens
1161 in the database and executes continuous checks and processes all the data.
1162 The two applications (gcm_input and gcm_daemon) together are the core of the central system. 
1163 The application has the following tasks:
1164 <itemize>
1165 <item>Processing data into other tables so that easy detection can take place</item>
1166 <item>Raising notifications based on the available input</item>
1167 <item>Maintain the status of notifications and changing priority when needed</item>
1168 <item>Periodically perform checks for alerts that are communicated through the notification-table</item>
1169 <item>Perform updates on the database when a new version of the software is loaded</item>
1170 </itemize>
1171 </para>
1172
1173 <subsection>
1174 <heading>Performing checks</heading>
1175
1176 <para>
1177 One of the most difficult tasks for the daemon is performing the automatic checks.
1178 Every check is different and will be made up of several parameters that have to test negative.
1179 That makes it hard to define this in software.
1180 Another downside is that some work may be very redundant.
1181 For that reason a more generic control structure is needed based on the technologies used.
1182 The logical choice is then to focus on the capabilities in the database and perform
1183 the job by executing queries.
1184 </para>
1185 <para>
1186 Since the system is about detecting problems and issues we build the detection in
1187 such a way that queries on the database result in 'suspicious' log records.
1188 So called 'innocent' records can be ignored. So if a query gives a result a
1189 problem is present, if there is no result there isn't a problem.
1190 As soon as we seek for common ground in the process of identifying problems
1191 it can be said that all results are based on the log-table
1192 (as stated in the manifest the log-table is the one and only table were input
1193 will arrive and stored for later use).
1194 Furthermore there are two ways of determining if a problem is present: 
1195 <itemize>
1196 <item>
1197 A single log-record or a group of log-records is within or outside the boundaries set.
1198 If it is outside the boundaries the log record(s) is/are a potential problem.
1199 If there are more boundaries set all of these need to be applied.
1200 Based on fixed data results can be derived.
1201 </item>
1202 <item>
1203 A set of records outline a trend that throughout time may turnout
1204 to be a problem. These type of values are not fixed and directly legible
1205 but more or less derived data. That data is input for some checks (previous bullet).
1206 </item>
1207 </itemize>
1208 In both cases a set of queries can be run.
1209 If there are more queries to be executed the later queries can be executed on
1210 only the results. For that reason intermediate results have to be stored in a
1211 temporary table for later reuse.
1212 Saving a session in combination with the found log-records are sufficient.
1213 This is also true since log records are the basis of all derived presences in
1214 the numerous log_adv_xxx-tables and always have a reference to the log-table. 
1215 </para>
1216 <para>
1217 Building the checks will thus be nothing more than combining queries
1218 and adding a classification to the results of that query.
1219 If this generic structure is being built properly with a simple (easy to understand) interface,
1220 many combinations can be made. People having a logically correct idea,
1221 but insufficient skills to program will be able to build checks.
1222 As a consequence we can offer the interface to the user,
1223 that in turn can also make particular checks for the environment that is unique to him/her.
1224 This - of course - doesn't mean that a clear SQL-interface shouldn't be offered.
1225 </para>
1226 <para>
1227 Whenever something happens, that is less than standard a line will be written to the syslogd.
1228 This will enable users and developers to trace exactly what happened.
1229 The gcm_daemon will also log startup and ending so that abrupt endings of the daemon will be detected.
1230 </para>
1231 </subsection>
1232
1233 <subsection>
1234 <heading>The initial process</heading>
1235 <para>
1236 When gcm_daemon starts first some basic actions take place that go beyond
1237 just opening a connection to the database. The following actions also need to take place:
1238 <itemize>
1239 <item>
1240 Check the database version if it is still the most recent version.
1241 The daemon will check the version-number of the database.
1242 If the database is not the same version as gcm_daemon an update will be performed.
1243 When the database is up-to-date normal processing will continue.
1244 </item>
1245 <item>
1246 If the database reflects that the used version gcm_daemon is less recent than
1247 the running version (i.e. a new version has been installed) all records
1248 in the log-table that weren't recognized before will now be set to unprocessed since
1249 there is a fair change that they might be recognized this time. This will ensure that no data is lost.
1250 </item>
1251 </itemize>
1252 </para>
1253
1254 </subsection>
1255 </section>
1256
1257 <section>
1258 <heading>Design ideas</heading>
1259
1260 <para>
1261 Use of a neural network to analyze system logs:
1262 <itemize>
1263 <item>Classify words</item>
1264 <item>Classify message based on word classification</item>
1265 </itemize>
1266 </para>
1267 </section>
1268
1269 </chapter>
1270
1271 </book>
1272 </doc>