New ideas are welcome. Most of change requests so far were about additional log data or filtering capabilities, therefore most of development/changes is expected in that area, and the workflow is optimised for it too.
More advanced changes or change proposals are also welcome. You are advised to read this document first, and then if you still have questions, proceed to internals/README.md and then to Snoopy source code itself.
Development of Snoopy is (and should) be done on fairly recent OS releases. Ubuntu 14.04 would be a good choice ATM, or RedHat/CentOS 7.
Required versions of software:
- automake 1.11
- autoconf 2.69
- libtool
With a few tweaks Snoopy can be built from git repository on older systems too.
The main incompatibility is that older autotools can not use external command to determine version of current Snoopy code your are building. Here is the diff of required change to make it work:
diff --git a/configure.ac b/configure.ac
index b71aa32..07edd5a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,7 +9,7 @@
AC_PREREQ([2.63])
AC_INIT(
[Snoopy Logger],
- m4_esyscmd_s(echo $(./build/get-version.sh)),
+ [2.4.4-my-dev-version],
[https://github.com/a2o/snoopy/issues/],
[snoopy],
[https://github.com/a2o/snoopy/])
After you have performed this change, you may re-run ./bootstrap.sh with an
argument to ignore too-old version of autotools:
This change is now performed automatically by bootstrap.sh, and a warning
is emitted. If you would like to get rid of the warning too, use this:
./bootstrap.sh geezer-os
IMPORTANT NOTICE: Pull requests that "fix" this build process "bug" on these obsolete OSes (by removing usage of external command and replacing it with static string) will be rejected.
File INSTALL.md contains detailed instructions about git repository cloning and git submodule initialization. Also, do not forget to run ./bootstrap.sh after submodules have been updated.
Recap of the steps:
git clone https://github.com/a2o/snoopy.git
cd snoopy
git submodule init
git submodule update
./bootstrap.sh
- data sources are located in src/datasource/;
- data source names should be lower case, with underscores for word separation;
- data about currently executing process is available in src/inputdatastorage.* files. Consult existing data sources on how to use it (filename for example);
- each data source must be self-sufficient. Do not rely on other parts of Snoopy;
- each data source must be tidy (free all mallocs, close all file descriptors);
- the first argument passed to each provider is a char array to return message into;
- data source message must not be longer than SNOOPY_DATASOURCE_MESSAGE_MAX_SIZE;
- each data source must have a corresponding header file;
- all data sources must build with -Wall -Werror -strict -std=c99 flags (enabled by default);
- code indentation: 4 spaces, no tabs;
- reserved data source names:
- snoopy*
- IMPORTANT: Every data source must have corresponding test(s) in tests/datasource/ directory, which enables automated testing for all upcoming changes. This enabled future developers.
- IMPORTANT: All tests must pass! If your new implementation broke something, fit it.
If you have developed a shiny new data source and you would like to start using it with Snoopy, you have to add it to the following files to make Snoopy fully aware of it:
- src/datasource/NAME.h (your data source's main header file)
- src/datasource/NAME.c (your data source's main source code goes here)
- src/datasource/Makefile.am (one reference)
- src/datasourceregistry.c (three references - header, name and function name)
- tests/datasource/Makefile.am (one reference, may contain multiple tests)
- tests/datasource/datasource_NAME.sh (single test or)
- tests/datasource/datasource_NAME-test1.sh (multiple tests)
- tests/datasource/datasource_NAME-test2.sh
- configure.ac (one reference)
- config.h.in (one reference, autogenerated by ./bootstrap.sh)
- etc/snoopy.ini.in (one reference in comments, for documentation purposes)
- ChangeLog (short description of new feature)
Rules for filter development are the same as for new data source development, with the following additional specifics:
- filters are located in src/filter/;
- each filter is passed two arguments:
- logMessage and
- filter argument (if any, otherwise an empty string is passed);
- filter argument is literal. If it contains multiple arguments (separated by comma, for example), the filter itself must do the parsing/tokenization.
- filter MAY modify logMessage. If it does so, the new log message MUST NOT EXCEED the maximum log message size, defined in snoopy.h.
- filter MUST return SNOOPY_FILTER_PASS or SNOOPY_FILTER_DROP constant;
- if SNOOPY_FILTER_DROP is returned by filter, it causes immediate termination of filter chain processing and message is not logged to syslog;
- reserved filter names:
- snoopy*
- filter tests are located in tests/filter/
If you have developed a shiny new filter and you would like to start using it with Snoopy, you have to add it to the following files to make Snoopy fully aware of it:
- src/filter/NAME.h (your filter's main header file)
- src/filter/NAME.c (your filter's main source code goes here)
- src/filter/Makefile.am (one reference)
- src/filterregistry.c (three references - header, name and function name)
- tests/filter/Makefile.am (one reference, may contain multiple tests)
- tests/filter/filter_NAME.sh (single test or)
- tests/filter/filter_NAME-test1.sh (multiple tests)
- tests/filter/filter_NAME-test2.sh
- configure.ac (one reference)
- config.h.in (one reference, autogenerated by ./bootstrap.sh)
- etc/snoopy.ini.in (one reference in comments, for documentation purposes)
- ChangeLog (short description of new feature)
Rules for new output development are the same as for new filter development, with the following additional specifics:
- outputs are located in src/output/;
- as output names are generally very generic, files and functions are suffixed with "...output";
- each output is passed three arguments:
- logMessage
- flag whether logMessage is a regular Snoopy log message or an error message
- output argument string (might not be used by output)
- output argument is literal. If it contains multiple arguments (separated by comma, for example), the output itself must do the parsing/tokenization.
- reserved output names:
- snoopy*
- output tests are located in tests/output/
If you have developed a shiny new output and you would like to start using it with Snoopy, you have to add it to the following files to make Snoopy fully aware of it:
- src/output/NAME.h (your output's main header file)
- src/output/NAME.c (your output's main source code goes here)
- src/output/Makefile.am (one reference)
- src/outputregistry.c (three references - header, name and function name)
- tests/output/Makefile.am (one reference, may contain multiple tests)
- tests/output/output_NAME.sh (single test or)
- tests/output/output_NAME-test1.sh (multiple tests)
- tests/output/output_NAME-test2.sh
- configure.ac (one reference)
- config.h.in (one reference, autogenerated by ./bootstrap.sh)
- etc/snoopy.ini.in (one reference in comments, for documentation purposes)
- ChangeLog (short description of new feature)
The most obvious thing that data sources, filters and outputs might have in common is argument parsing. If your new feature accepts a comma-separated argument list, then you are encouraged to use provided implementation. Consult file src/filter/only_uid.c to see an actual usage of said implementation.
That is it. Happy hacking! :)