Giter Club home page Giter Club logo

stumpless's Introduction

Goatshriek at a Glance

I'm a C and Ruby fan who's always looking to learn more about how things work. For that reason my projects tend to vary as I find new and interesting things to dig into, but I do have a few projects that I consistently work on.

Main Projects

  • Stumpless is a passion project to take something very simple (logging) and do it very well. I've used it as a way to learn and incorporate all sorts of development technologies from build platforms to Continuous Integration solutions, and continue to learn new things from it every day, from the finer parts of C programming to how to build and package a portable library that will run anywhere! Because this project started primarly as a learning tool for myself, I make sure that there are always good first issues for anyone looking to learn more about OSS contribution to try out. If you want to get involved in Open Source and want to kick the tires on a contribution that's more than adding your name to a text file, this is a great place to start!
  • Ruby Dragon is a plugin for NSA's Ghidra SRE tool that allows you to use more languages than the Java and Jython options that come standard. It's a reflection of my love of learning new programming languages and belief that you should be able to use any tool from any language. If you have a JVM-based language you think should be included, be sure to open an issue for it to get added!
  • Wrapture is a project that started out as a simple script in stumpless to create C++ wrappers for the library. It's under active work to become a full-fledged code generation tool for wrapping C libraries in other languages, but has a ways to go yet. For the time being, you're better off checking out something like SWIG, GObject, or Haxe if you need to do this. But if you're really curious, star the repo and keep an eye on it - I do plan to make it a viable option in due time!

stumpless's People

Contributors

abhakta-47 avatar acass91 avatar alessandro-murtas avatar angiethompsonnn avatar anindyasen avatar ash-kamrip avatar dylmcgold avatar goatshriek avatar harry-ramsey avatar hoomaac avatar igorkole avatar inquisitev avatar jagw-mobica avatar jk-bit avatar kirubaspace avatar lilrawry avatar lockna avatar miroslav263 avatar momori256 avatar msa360 avatar northernsage avatar osmanbuyuksar avatar panosfol avatar pedestrianlove avatar rmknan avatar sakshi-75 avatar taliezincho avatar tylerstanish avatar ulisesten avatar viveknshah avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stumpless's Issues

refactor tests for invalid format items

Tests for names and other elements with formatting errors use much of the same code, and could be made more compact by refactoring the common code into helper test functions. Some documentation on creating and using test helpers can be found in test/README.md and docs/test.md

See the discussion of #184 for the context behind this request.

implement french (fr-FR) localization

Localization has been added to the library, and fr-FR was added with stub values to support testing. However, these messages are not useful and need to be replace with actual French to be of any use.

This will be straightforward for someone that speaks the language, even if you have very little knowledge of C. You will simply need to update the strings in include/private/config/locale/fr-fr.h with French strings (in UTF-8 encoding). If you want to see what the English message is, check the values in include/private/config/locale/en-us.h.

While Building the stumpless facing issues in centos 7

Describe the bug
the command
make bench
fails

To Reproduce
Try installaing in Centos 7 with Gnu c++ compiler.

Expected behavior
Installation (and bench) fails with following

[100%] Built target benchmark
[100%] Built target test_helper_server
[100%] Built target stumpless
[100%] Building CXX object CMakeFiles/performance-test-network.dir/test/performance/target/network.cpp.o
In file included from xxxx/stumpless/test/performance/target/network.cpp:29:0:
xxxx/stumpless/include/test/helper/server.hpp:29:25: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
 #    define BAD_HANDLE -1
                         ^
xxxx/stumpless/test/performance/target/network.cpp:40:30: note: in expansion of macro ‘BAD_HANDLE’
     socket_handle_t handle = BAD_HANDLE;
                              ^
xxxx/stumpless/include/test/helper/server.hpp:29:25: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
 #    define BAD_HANDLE -1
                         ^
xxxx/stumpless/test/performance/target/network.cpp:41:32: note: in expansion of macro ‘BAD_HANDLE’
     socket_handle_t accepted = BAD_HANDLE;
                                ^
xxxx/stumpless/test/performance/target/network.cpp: In member function ‘virtual void Tcp4Fixture_AddEntryToTcp4Target_Benchmark::BenchmarkCase(benchmark::State&)’:
xxxx/stumpless/test/performance/target/network.cpp:79:12: error: ‘_’ does not name a type
   for(auto _ : state){
            ^
xxxx/stumpless/test/performance/target/network.cpp:87:3: error: expected ’ before ‘state’
   state.counters["CallsToAlloc"] = ( double ) tcp4_memory_counter.malloc_count;
   ^
xxxx/stumpless/test/performance/target/network.cpp:88:81: error: expected ‘)’ before ‘;’ token
   state.counters["MemoryAllocated"] = ( double ) tcp4_memory_counter.alloc_total;
                                                                                 ^
In file included from xxxx/stumpless/test/performance/target/network.cpp:29:0:
xxxx/stumpless/test/performance/target/network.cpp: At global scope:
xxxx/stumpless/include/test/helper/server.hpp:29:25: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
 #    define BAD_HANDLE -1
                         ^
xxxx/stumpless/test/performance/target/network.cpp:98:30: note: in expansion of macro ‘BAD_HANDLE’
     socket_handle_t handle = BAD_HANDLE;
                              ^
xxxx/stumpless/include/test/helper/server.hpp:29:25: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
 #    define BAD_HANDLE -1
                         ^
xxxx/stumpless/test/performance/target/network.cpp:99:32: note: in expansion of macro ‘BAD_HANDLE’
     socket_handle_t accepted = BAD_HANDLE;
                                ^
xxxx/stumpless/test/performance/target/network.cpp: In member function ‘virtual void Tcp6Fixture_AddEntryToTcp6Target_Benchmark::BenchmarkCase(benchmark::State&)’:
xxxx/stumpless/test/performance/target/network.cpp:137:12: error: ‘_’ does not name a type
   for(auto _ : state){
            ^
xxxx/stumpless/test/performance/target/network.cpp:145:3: error: expected ‘;’ before ‘state’
   state.counters["CallsToAlloc"] = ( double ) tcp6_memory_counter.malloc_count;
   ^
xxxx/stumpless/test/performance/target/network.cpp:146:81: error: expected ‘)’ before ‘;’ token
   state.counters["MemoryAllocated"] = ( double ) tcp6_memory_counter.alloc_total;
                                                                                 ^
xxxx/stumpless/test/performance/target/network.cpp: In member function ‘virtual void Udp4Fixture_AddEntryToUdp4Target_Benchmark::BenchmarkCase(benchmark::State&)’:
xxxx/stumpless/test/performance/target/network.cpp:186:12: error: ‘_’ does not name a type
   for(auto _ : state){
            ^
xxxx/stumpless/test/performance/target/network.cpp:190:3: error: expected ‘;’ before ‘state’
   state.counters["CallsToAlloc"] = ( double ) udp4_memory_counter.malloc_count;
   ^
xxxx/stumpless/test/performance/target/network.cpp:191:81: error: expected ‘)’ before ‘;’ token
   state.counters["MemoryAllocated"] = ( double ) udp4_memory_counter.alloc_total;
                                                                                 ^
xxxx/stumpless/test/performance/target/network.cpp: In member function ‘virtual void Udp6Fixture_AddEntryToUdp6Target_Benchmark::BenchmarkCase(benchmark::State&)’:
xxxx/stumpless/test/performance/target/network.cpp:231:12: error: ‘_’ does not name a type
   for(auto _ : state){
            ^
xxxx/stumpless/test/performance/target/network.cpp:235:3: error: expected ‘;’ before ‘state’
   state.counters["CallsToAlloc"] = ( double ) udp6_memory_counter.malloc_count;
   ^
xxxx/stumpless/test/performance/target/network.cpp:236:81: error: expected ‘)’ before ‘;’ token
   state.counters["MemoryAllocated"] = ( double ) udp6_memory_counter.alloc_total;
                                                                                 ^
make[3]: *** [CMakeFiles/performance-test-network.dir/test/performance/target/network.cpp.o] Error 1
make[2]: *** [CMakeFiles/performance-test-network.dir/all] Error 2
make[1]: *** [CMakeFiles/bench.dir/rule] Error 2
make: *** [bench] Error 2

Build Environment
Describe your build environment and any other factors that contribute to the configuration of Stumpless. This should include:

  • CentOS Linux release 7.6.1810 (Core)
  • cmake version 3.18.0
  • gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)

Additional context
The Problem is that we are not passing the -std=c++11 to the compiler. In order to do that the following is change is made to cmakelists.txt.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4fdcb4f..b438587 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,6 +36,8 @@ set(FALLBACK_PAGESIZE 4096
   CACHE STRING "the memory page size to use if it cannot be detected at runtime"
 )
 
+set (CMAKE_CXX_STANDARD 11)
+
 string(CONCAT benchmark_path_help_string
   "A directory with a build of google benchmark that can be used instead of "
   "downloading and building the library during build. "

add systemd journal target

Logging to the systemd journal is an important feature, and needs to be added as a target type. The C API for this is held in the systemd/sd-journal.h, a prerequisite for this target to be supported.

sd-journal does support a form of structured logging, and so logging of entries with structured data should utilize this to the extent possible. The implementation will need a clearly defined and documented way to map elements and params into the key/value pairs allowed by sd-journal.

This would also be a great way to learn the systemd journal logging mechanisms.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

length checking of element names

The syslog RFC (RFC 5424) specifies a maximum length for many fields of a log message, including element names. Checking the length of supplied element name arguments will not only help users stay compliant with the standard, but will also allow for efficiencies in the implementation by eventually allowing for the use of fixed-length buffers instead of memory allocated from the heap.

As specified in the RFC, element names should be checked for their length and rejected if they are more than the allowed length (32 characters). Note that this length does not include the terminating NULL character from the C string representation.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

There are a number of functions that allow element names to be supplied - the constructor for elements, and the functions that allow new elements to be added to entries directly. Since this check will need to take place in several places, you will be best served by implementing it in a single function and then calling it wherever required.

Declare your new function (something like validate_element_name_length) in include/private/validate.h, and define it in src/validate.c. Similar validation functions have already been created for msgids and app names - use them as a reference as needed. After your new function has been defined, add calls to it wherever a element name is passed as a parameter in the library, which are the following functions:

  • stumpless_new_element (in src/element.c)
  • stumpless_set_element_name (also in src/element.c)
  • stumpless_add_new_element (in src/entry.c)
  • stumpless_add_new_param_to_entry (in src/entry.c)

Note that you don't need to validate names passed to search functions like stumpless_get_element_by_name as the search will simply fail for non-compliant names.

Update the documentation for each of these functions to specify that the element name length is restricted to be 32 characters or less. The relevant documentation is in a doxygen comment format in the include files corresponding to the source files (include/stumpless/element.h and include/stumpless/entry.h). Add the note about this to the @param descriptions of the element name parameters.

An error already exists that should be used for invalid element names: STUMPLESS_ARGUMENT_TOO_BIG. Raise this error in your validation function if an element name that is too long is detected, using the raise_argument_too_big function from src/error.c. Again, the existing validation functions for msgids and app names are good references to look at.

Don't forget to add tests for your new functionality! These should go alongside the tests for the functions that have element names - check test/function/element.cpp and test/function/entry.cpp for existing tests for these functions, and add new tests that make sure that element names that are too long are rejected.

implement NDELAY option

Stumpless currently does not support the STUMPLESS_OPTION_NDELAY option despite providing it in its header files. This option is meant to mirror the LOG_NDELAY option in functionality. The meaning may change across target types though - this will need to be thought through, defined, and documented for each of the target types.

Don't forget to document the option after you implement it in include/stumpless/option.h.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

implement element to string function

It is often useful to be able to obtain a string representation of a given value either for user interface hints, troubleshooting, or operations like value comparison. Such a function is currently implemented for some stumpless data types (like the version struct) but not for others, including the element struct.

Note that this function is not intended for use in the formatting of a log message as this output may be subtly different, for example when escape codes are needed. Rather, it is meant to give an as-is represenation of the element itself (name and all params).

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

Before you start, take a peek at bb30c61 which implements a similar functionality for params. You will need to use the function implemented here, and the basics of this change will also apply to this one as well.

First, read this specific section of the development guide devoted to adding new functions. It provides an outline of the work you will need to do beyond the implementation and testing of the function.

Next, add a declaration for your function in the include/stumpless/element.h header file. Name the function stumpless_element_to_string and document its behavior in the same doxygen format as the others in the same header. Make sure to cover the following points:

  • the general format of the output (suggested: <name> (with no params), <name>:[param_1_to_string,param_2_to_string,etc.] with params)
  • the supplied argument should be a const pointer
  • explicitly state that the result must be freed when it is no longer needed

Now you are ready to add the matching implementation for the function in src/element.c. Use the code for existing functions in this file as examples. You will also need to use stumpless_param_to_string to get the string representation of any params in the element. Be sure that there is no memory leak in your result, and try to avoid expensive operations like sprintf - you should be able to do this with memcpy calls and assignments, and perhaps strlen calls. You may consider refactoring some common portions of stumpless_param_to_string into separate private functions that can be used in both places for efficiency, but don't worry if you don't want to go this far - it can be turned into a follow-on first issue for others to tackle.

Finally, be sure to add tests for the new function. These should go in test/function/element.cpp and should achieve full coverage, including for memory allocation failure and NULL argument cases. Again, there are already similar test cases for other functions in this file that you can look at to get a general idea of how the tests should be structured.

Refactoring common portions of stumpless_param_to_string and stumpless_element_to_string

This is just a follow up issue to improve on #180.

Quoting from #146:

You may consider refactoring some common portions of stumpless_param_to_string into separate private functions that can be used in both places for efficiency...

Since #180 did not implement the changes described above I'll go ahead and work on a separate PR for this. I have opened the issue only to document my intent in doing so and to have somewhere to discuss related changes if the need arises.

length checking of the app-name

The syslog RFC (RFC 5424) specifies a maximum length for many fields of a log message, including the app-name field. Checking the length of supplied app-name arguments will not only help users stay compliant with the standard, but will also allow for efficiencies in the implementation by eventually allowing for the use of fixed-length buffers instead of memory allocated from the heap.

As specified in the RFC, app-name parameters should be checked for their length and rejected if they are more than the allowed length (48 characters). Note that this length does not include the terminating NULL character from the C string representation.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

There are a number of functions that allow an app-name to be supplied - the constructor for entries, the set feature for the app-name of entries, and the default app-name setting for targets, to list a few. Since this check will need to take place in several places, you will be best served by implementing it in a single function and then calling it wherever required.

Declare your new function (something like validate_app_name_length) in include/private/validate.h, and define it in src/validate.c. A similar validation function has already been created for msgids - use it as a reference as needed. After your new function has been defined, add calls to it wherever an app-name is passed as a parameter in the library, which are the following functions:

  • vstumpless_new_entry (in src/entry.c)
  • stumpless_set_entry_app_name (in src/entry.c)
  • stumpless_set_target_default_app_name (in src/target.c)

Update the documentation for each of these functions to specify that the app name length is restricted to be 48 characters or less. The relevant documentation is in a doxygen comment format in the include files corresponding to the source files (include/stumpless/entry.h and include/stumpless/target.h). Add the note about this to the @param descriptions of the app-name parameters.

An error already exists that should be used for invalid app-names: STUMPLESS_ARGUMENT_TOO_BIG. Raise this error in your validation function if an app-name that is too long is detected, using the raise_argument_too_big function from src/error.c. Again, the existing validation function for msgids is a good reference point to look at.

Don't forget to add tests for your new functionality! These should go alongside the tests for the functions that have app-names - check test/function/target.cpp and test/function/entry.cpp for existing tests for these functions, and add new tests that make sure that app-names that are too long are rejected.

format checking of param names

The syslog RFC (RFC 5424) specifies that a number of fields only include printable ASCII characters (decimal values 33 to 126 inclusive), including structured data identifiers such as param names. In addition to being limited to printable ASCII, identifiers have even more restricted characters that are not allowed. Checking the characters of supplied identifiers will not only help users stay compliant with the standard, but will also provide a point of mitigation for encoding bugs and vulnerabilities.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block.

There are a number of functions that allow a param name to be supplied: the constructor for params, accessor and mutator functions for entries and elements. Since this check will need to take place in several places, you will be best served by calling a single function wherever required.

A validation function already exists to check that a string only contains printable ASCII characters: validate_printable_ascii in src/validate.c. You will need to define a new function in the same file for structured data identifiers, adding the restriction that the string also not contain these characters and raising an encoding error if it does:

  • an equal sign =, decimal value 61
  • a closing brace ], decimal value 93
  • a double-quote character ", decimal value 34

After this addition, add calls to your new function in functions where a param name is passed as a parameter in the library, which are listed below. For functions where the parameter is used for a search, be sure to check the name before acquiring any locks to avoid deadlock and improve performance.

  • stumpless_new_param (in src/param.c) This function is used by all others that create a new param, and so explicit checks are not needed in those.
  • stumpless_set_param_name (in src/param.c) This function is used by all others that modify a param name, and so explicit checks are not needed in those.
  • stumpless_element_has_param (in src/element.c)
  • stumpless_get_param_by_name (in src/element.c)
  • stumpless_get_param_index (in src/element.c)
  • stumpless_get_param_name_count (in src/element.c)
  • stumpless_get_param_value_by_name (in src/element.c)
  • stumpless_get_entry_param_by_name (in src/entry.c)
  • stumpless_get_entry_param_value_by_name (in src/entry.c)

Update the documentation for the first two of these functions (creation and modification) to specify that the param name is restricted to specific characters. The relevant documentation is in a doxygen comment format in the include/stumpless/param.h header file. Add the note about this to the @param descriptions of the param name parameters.

Don't forget to add tests for your new functionality! These should go alongside the tests for the functions that have param names. Find the existing tests for these functions as starting points, and add new tests that make sure that param names with printable but invalid characters are rejected.

implement PID option

Stumpless currently does not support the STUMPLESS_OPTION_PID option despite providing it in its header files. This could easily be implemented by checking the target's setting for this option during formatting, and using NILVALUE (a dash character) if this option is not set.

This option should be off by default, being enabled by stumpless_set_option on a target. This is a change in current behavior, but brings the library closer to the behavior described by syslog, which this library currently attempts to stay in line with where possible and reasonable.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

First, have a look at the documentation for stumpless_get_option, stumpless_set_option, and stumpless_unset_option in include/stumpless/target.h. You will not need to modify any of these, but you will use them in your implementation so they are important to understand.

Next, check out stumpless_add_entry in src/target.c. This is the workhorse function for logging messages, and includes the calls to format messages before sending them. The formatting call currently only uses the stumpless_entry struct to create the message, but this will not be enough to tell if the target's option is set.

There are a few possible solutions. You could add a completely new formatting function (something like format_entry_without_pid) to src/formatter.c that does not use the procid of the entry. You could change the current formatting function to also take a pointer to the stumpless_target struct that it can use to check the option while formatting. You could change the current formatting function to simply take a boolean switch on whether to use the pid or not. Or you could solve it a different way. The specific approach is up to you - just make sure that you can explain why you feel it's the best approach. The end result should be that if STUMPLESS_OPTION_PID is not set on the target, then the PROCID field of the logged message is a single dash character, the RFC 5424 NILVALUE.

Once this is done, add some tests to make sure that the behavior is as intended. Test code already exists to make sure that setting and unsetting the option behaves as expected - look for TEST( SetOption, Pid ) in test/function/target.cpp. Use this test as a starting point to create a new test that logs a message before and after setting the option. The message logged before the option is set should not include the pid. The message logged after should have it. To detect whether the pid section is a dash or a value will require some work - you could write your own regex, or check out the Google Mock matchers to perhaps make this easier. For details on the format of the messages, you can refer to the RFC that stumpless follows (don't let the RFC intimidate you, the format section is pretty easy to follow).

error codes are not included in perror output

The error id is not included in the output of stumpless_perror, which could add some extra steps when troubleshooting. The goal of the perror function is to prevent manual print statements, and there is also not a way to easily get the name of the error even if the code itself is retrieved (as it will be an integer and not a string).

This could easily be solved by adding a new public function like stumpless_get_error_id_string that spits out a string representation of an error id enum. This could then be used in the perror function to add the error id in an easily readable format.

implement format checking of element names

The syslog RFC (RFC 5424) specifies that a number of fields only include printable ASCII characters (decimal values 33 to 126 inclusive), including structured data identifiers such as element names. In addition to being limited to printable ASCII, identifiers have other restricted characters that are also not allowed. Checking the characters of identifiers will not only help users stay compliant with the standard, but will also provide a point of mitigation for encoding bugs and vulnerabilities.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block.

A similar issue for param names has already been tackled, and is a great place to review if you want some more preparation material. Check out the excellent work by Gabriel Fioravante in #177 and #184 for inspiration.

There are a number of functions that allow a element name to be supplied: the constructor for elements, accessor and mutator functions for entries and elements. Since this check will need to take place in several places, you will be best served by calling a single function wherever required.

A validation function already exists to check that a string contains only allowed characters: validate_param_name in src/validate.c. You will need to either copy this function and change the copy for element names or refactor the current one (via rename) to support both.

After this change, add calls to your new function wherever an element name is passed as a parameter in the library, which are listed below. For functions where the element name is used for a search, be sure to check the name before acquiring any locks to avoid deadlock and improve performance.

  • stumpless_new_element (in src/element.c) This function is used by all others that create a new element, and so explicit checks are not needed in those.
  • stumpless_set_element_name (in src/element.c) This function is used by all others that modify an element name, and so explicit checks are not needed in those.
  • stumpless_entry_has_element (in src/entry.c)
  • stumpless_get_element_by_name (in src/entry.c)
  • stumpless_get_element_index (in src/entry.c)
  • stumpless_get_entry_param_by_name (in src/entry.c)
  • stumpless_get_entry_param_value_by_name (in src/entry.c)

Update the documentation for the first two of these functions (creation and modification) to specify that the element name is restricted to specific characters. The relevant documentation is in a doxygen comment format in the include/stumpless/element.h header file. Add the note about this to the @param descriptions of the element name parameters.

Don't forget to add tests for your new functionality! These should go alongside the tests for the functions that have element names. Find the existing tests for these functions as starting points, and add new tests that make sure that element names with printable but invalid characters are rejected.

add support for colored terminal output

A convenient feature in any logging library is colored output when logging to a console so that messages of different severity levels stand out from one another. This could be implemented in stumpless as a new set of attributes for stream loggers, which is off by default but is set when getting the stdout our stderr targets using stumpless_open_stdout_target or stumpless_open_stderr_target (respectively).

Bonus points if you can also implement build-time configuration options to set the default severity colors! However, if you aren't feeling up to this part then it can be split out into a separate issue for someone else to try their hand at - just make a note of this when you announce that you're going to work on this.

Check out the Contributing Guidelines and the development guide for the basics on working with the stumpless code base and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here and someone can help you get past the stumbling block.

If you aren't familiar with printing colors in terminals, first do some research on the topic. This article has a good walkthrough of the concepts for beginners.

include/stumpless/target/stream.h declares the public functions that are specific to stream targets. This is where you will need to add a new function to set the color for a severity code. Name the function something like stumpless_set_severity_color and will take a target, a severity code, and an escape code as arguments. Put the definition for this into the src/target/stream.c file.

Make sure that your implementation is thread safe! The simplest way to do this is to lock the target whenever it is being modified or read for the values, using the lock_target and unlock_target functions.

You'll need somewhere to store the configured colors. They should be added to the struct that stores details for stream targets, defined in include/private/target/stream.h. Exactly how the codes are stored is up to you, for example it could be an array of pointers to strings. Your new function for setting the color will update this field with the desired value. You should add code to stumpless_open_stream_target in src/target/stream.c to initialize these fields with something that means off (NULL pointers, perhaps)?

To set these up for stdout and stderr targets by default, just add some calls to your new set color functions to stumpless_open_stderr_target and stumpless_open_stdout_target (in src/target/stream.c) with some default colors that make sense. For example STUMPLESS_SEVERITY_EMERG should probably be something alarming like red!

Next take a look at the sendto_stream_target function in src/target/stream.c. This function is responsible for writing messages to a stream target. This is the function where you will add calls to print the escape codes before and after the message to color it. Before the message you will print the configured color escape code, and afterwards you will print the escape code to clear the colors back to what they were before.

Finally, remember to add new tests for your code in test/function/target/stream.cpp. You can use the other tests that are already there as starting points.

allow runtime specification of console output

Stumpless will eventually be capable of writing some output to the console, for example once the CONS option is implemented (see #78). However, there is currently not a way to set the stream used for this, as there is for error streams for example. This could create difficulties for some use cases of the library, and at a minimum will make testing more difficult. This could be fixed by implementing two functions called stumpless_get_console_stream and stumpless_set_console_stream which operate as named.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

First, check out the documentation and definitions of stumpless_get_error_stream and stumpless_set_error_stream in include/stumpless/error.h and src/error.c, respectively. These function very similarly to what you will be implementing and serve as a great template for getting started. Pay special attention to the variables they work with and how they are initialized. These functions use atomic variables to maintain thread safety while they operate.

Next, you need to add these two functions and their supporting variables. The best place for them currently is the target module (include/stumpless/target.h and src/target.c), which will need to write to the specified stream in the event of a failure once #78 is implemented. As you add your functions, also be sure to add them to the Windows definition file (src/windows/stumpless.def) and the header check tool in tools/check_headers/stumpless.yml. The Adding New Functions section of the development guide talks about this in more detail.

Once you have these added and documented, you just need to add some tests to ensure that they are covered. Your tests will be fairly simple, consisting of the following checks:

  1. Make sure that the default console is stdout
  2. Make sure that the stream is changed after calling set on it.
  3. NULL is a valid argument to set the console. This should result in any output meant for the stream simply getting dropped, effectively removing the stream.

These tests should be added to the target test suite in test/function/target.cpp, which has a large number of other tests that you can use for comparison. There are some stream setting tests for the existing error stream get/set functionality in test/function/error.cpp that you can also draw inspiration from.

target locking operations cause undefined behavior in unsupported target types

The multithreading locks in the target structure cause problems for stack-allocated target structures. This needs to be changed so that this space is accounted for in applications that wish to support stack-allocated target operations.

This was raised as a more serious issue in #202 due to sporadic failures of the unsupported target type tests, which use stack-allocated structures to create an unsupported target type.

string conversion function for severity levels

It is often useful to be able to obtain a string representation of a given value either for user interface hints, troubleshooting, or operations like value comparison. Such a function is currently implemented for some stumpless data types (like the error id enumeration) but not for others, including the severity enumeration.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

First, check out the implementation of stumpless_get_error_id_string in include/stumpless/error.h and src/error.c. The implementation and documentation of this function is very similar to what you should do for yours. Pay particular attention to the error_enum_to_string array, which provides a mapping from the enumeration value to the string itself.

Next, read this specific section of the development guide devoted to adding new functions. It provides an outline of the work you will need to do beyond the implementation and testing of the function.

Next, add a declaration for your function in the include/stumpless/severity.h header file. Name the function stumpless_get_severity_string and document its behavior in the same doxygen format as the others in the header. Make sure to cover the following points:

  • the format of the output (string literal of the symbol, perhaps give an example as well)
  • explicitly state that the result is a string literal that shouldn't be modified or freed by the caller

Now you are ready to add the matching implementation for the function in src/severity.c. Use the code for stumpless_get_error_id_string as an example.

Finally, you'll need to add tests for the new function. These should go in a new test suite, test/function/severity.cpp, and should achieve full coverage, including for a severity that doesn't exist. There is some documentation on adding a new test suite here, and the other test suites can serve as an example of what these should look like. A good test suite to copy and modify is the test/function/version.cpp file, which is relatively simple. For the tests themselves, some of the GetErrorId tests for stumpless_get_error_id_string in test/function/error.cpp are good tests to copy and modify as needed.

comparison function for versions

While the library provides a way to get the current version as a string or a custom struct, it does not provide an easy way to compare versions using semantic versioning principles. This functionality would be convenient for any users wishing to put a version guard in their code, for example to throw warnings if a major version number is incremented unintentionally. This would be a C-like version of the version specifications provided in Gemfiles in Ruby or requirements.txt files in Python.

This function should be called something like stumpless_version_cmp and should take two const stumpless_version structs as arguments. The return result will be an int following the same conventions as strcmp regarding less than, equal, or greater than. Only the major, minor, and patch values need to be compared - do not worry about semantic versioning concepts like build metadata or pre-release versions.

This is a good first issue, especially for anyone looking to get a stronger understanding of Semantic Versioning.

Check out the include/stumpless/version.h header and src/version.c source module to get a feel for the version struct and what an implementation of this might look like. The version test suite already exists at test/function/version.cpp and would just need to have a few tests added to it for the new function.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

string conversion function for facility levels

It is often useful to be able to obtain a string representation of a given value for user interface hints, troubleshooting, or operations like value comparison. Such a function is currently implemented for some stumpless data types (like the severity enumeration) but not for others, including the facility enumeration.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block.

First, check out a8b701d and the implementation of stumpless_get_severity_string in include/stumpless/severity.h and src/severity.c. The implementation and documentation of this function are very similar to what you should do for yours. Pay particular attention to the severity_enum_to_string array, which provides a mapping from the enumeration value to the string itself.

Next, read this specific section of the development guide devoted to adding new functions. It provides an outline of the work you will need to do beyond the implementation and testing of the function.

Next, add a declaration for your function in the include/stumpless/facility.h header file. Name the function stumpless_get_facility_string and document its behavior in the same doxygen format as the others in the header. Make sure to cover the following points:

  • the format of the output (string literal of the symbol, perhaps give an example as well)
  • explicitly state that the result is a string literal that shouldn't be modified or freed by the caller

Now you are ready to add the matching implementation for the function in src/facility.c. Use the code for stumpless_get_severity_string as an example.

Finally, you'll need to add tests for the new function. These should go in a new test suite, test/function/facility.cpp, and should achieve full coverage, including for a facility that doesn't exist. Once again, the easiest path to success here will be looking at what was done in a8b701d and doing something very similar. There is some documentation on adding a new test suite here, and the other test suites can serve as an example of what these should look like. A good test suite to copy and modify, of course, is the test/function/severity.cpp file.

add a new (spoken) language

If you know a language other than English and you're looking for a way to contribute to a project without knowing much about coding, adding a new locale is a great place to start.

There is a detailed guide on how to go about adding a new language that you know in the localization documentation. If you're feeling up to it, go ahead and open a new issue with the language you would like to add, and go to it!

Is the language that you wanted already added? Look over the locale header for it anyway (in include/private/config/locale/); any strings added after it was initially added will still be English placeholders marked with a // todo translate comment. A contribution translating these is almost as important as the initial translation, and is a much simpler change. Rather than implementing a completely new set of headers, you will just change the placeholder strings to be locale-specific strings instead. If you want to see a list of what strings need translating by locale, you can also use grep to get a current list:

grep -r -c "// todo translate" include/private/config/locale/

# output looks like this:
# include/private/config/locale/bg-bg.h:28
# include/private/config/locale/cz-cz.h:15
# include/private/config/locale/de-de.h:36
# include/private/config/locale/el-gr.h:16
# include/private/config/locale/en-us.h:0
# include/private/config/locale/es-es.h:18
# include/private/config/locale/fr-fr.h:36
# include/private/config/locale/it-it.h:0
# include/private/config/locale/pl-pl.h:17
# include/private/config/locale/sk-sk.h:31
# include/private/config/locale/sv-se.h:36

If there aren't any for your language or you'd rather do something new, have a look in the l10n folder of the repository. This has localized documentation for the project, and there are lots of opportunities to add a paragraph or two of translation. Don't feel like you need to translate an entire file for this, just a few paragraphs is more than enough! The l10n/zh-cn folder is a good example of what this could look like as more translations are added.

Missing version capability in headers

There needs to be a way to determine the version of the library in use. This should be in both the header files as a #define as well as from a function call, so that the version of the header files and of the shared library itself can be determined.

check target type in close functions

There is a specific function for closing each type of target, but it does not check the type of the target before closing. If passed the wrong type of target, this could lead to memory corruption and/or crashing.

While this would be a user error, a check for the target type would reduce the chance of this becoming a problem. A future build option to remove error checks if needed would allow the performance penalty to be removed if users can guarantee they won't violate this.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

First, take a look at the raise_target_incompatible function in include/private/error.h. You will use this function to raise an error when the wrong target type is detected.

You need a string to pass to the error raising function as the error message. Since there isn't an appropriate one existing, you will need to add a new one to the locales. Check out the documentation on localization for instructions on how to do this.

Implementing the actual checks is straightforward. For each close function (of the form stumpless_close_xxx_target) in the target modules (in the src/target/ directory), add a check on the target's type and raise an error (and return of course) if it is not the expected type.

Finally, add tests for each modification to make sure that trying to close the wrong target type is caught. For each target type, look at the existing test suite (these are in the test/function/target/ directory) and add a test for the close test with a different target type. A good starting place is the test that passes NULL into the function and checks for an error - copy this test and modify it to test for the new scenario.

socket targets may fail to bind to local socket when not provided

Socket targets can be opened with a local socket name provided, but this may also be set to NULL, in which case a local socket is generated (see the documentation of stumpless_open_socket_target for details). However, this socket is always the same, which means that if a target is not properly closed the local socket will remain. Successive targets will be unable to open, as they will attempt to bind to the same socket name and will fail as it already exists.

This could be fixed by adding some number of retries to the local socket name, ideally randomized so that the names are not linear. The solution should also be documented in the documentation, and of course tests for the fixed functionality should be created as well.

implement PERROR option

Stumpless currently does not currently have any equivalent of the LOG_PERROR option provided by traditional syslog implementations. This should be implemented as another option, and made compatible with LOG_PERROR on systems that have it.

The meaning of the option is simple (it is described briefly in the syslog manpage). Targets with this option set should also write their message to stderr as well as the target itself.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

First, have a look at the documentation for stumpless_get_option, stumpless_set_option, and stumpless_unset_option in include/stumpless/target.h. You will not need to modify any of these, but you will use them in your implementation so they are important to understand.

Next, check out stumpless_add_entry in src/target.c. This is the workhorse function for logging messages, and is a good place to put the logic to handle this option. The change will be simple - before calling the sendto function for the target, you will check to see if the option is set, and if it is, then print the formatted message to stderr.

Don't forget to document the option after you implement it in include/stumpless/option.h.

Once you have implemented this, be sure to add a test for the functionality. Test code already exists to make sure that setting and unsetting the option behaves as expected - look for TEST( SetOption, Pid ) in test/function/target.cpp. Use this test as a starting point to create a new test that logs a message before and after setting the option to make sure no runtime failures occur. It may be difficult to capture stderr itself for the test, and so if you cannot figure out a way to do this then it can be handled in a future change.

move network config wrappers to separate header

Stumpless uses a scheme involving #definenames and macro functions to separate its portability measures from the application logic itself. This was originally done via a single header, include/private/config/wrapper.h, but as the library grows this single header has become bloated. Now features are instead contained in their own dedicated wrapper headers. Older features need to be moved to their own as well to address the original problem.

Your task here is to factor out the network support wrappers into their own header. This is a good task for those with some C knowledge looking to learn about how to implement portability in a C application. As this is a refactoring task you can rely on the existing unit and integration tests as a safety net as you make changes and explore.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

First, read through the portability documentation to understand how portability is approached in the library.

Next, have a look at include/private/config/wrapper/journald.h. This header does the same wrapping for targets for systemd's journal service that the network support should. This is a great file to copy as a starting point and modify to suit your needs.

Finally, have a look at tools/check_headers/stumpless.yml and tools/check_headers/stumpless_private.yml. These files are used by a custom tool for header inclusion checks across the library's source code. For all symbols that you move to your new header file, you'll also need to change to point to your new header in these files. Any files that are present in stumpless.yml should be moved to stumpless_private.yml as well, as they were added before the public/private split in the yaml files was made. You'll see symbols for the journald and thread safety wrappers already in stumpless_private.yml as an example.

Once you have moved things to your new header and updated the header checking tool manifests, you can use the header check tool to tell you what files need to have their #include statements updated. You can find examples of how to run the tool in the testing workflow that does it, .github/workflows/analysis.yml, or you can use the one-liner included below. You will need Ruby to run the tool.

tools/check_headers/check_headers.rb "include/**/*.h*" "src/**/*.c" "test/**/*.cpp" "docs/examples/**/*.c"

Good luck!

implement CONS option

Stumpless currently does not support the STUMPLESS_OPTION_CONS option despite providing it in its header files. This option is meant to mirror the LOG_CONS option from syslog.h in functionality, which causes messages to be written to the system console if there is a problem sending them to the target.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

First, have a look at the documentation for stumpless_get_option, stumpless_set_option, and stumpless_unset_option in include/stumpless/target.h. You will not need to modify any of these, but you will use them in your implementation so they are important to understand. Also be sure to understand how stumpless_get_cons_stream works, as you'll need it to retrieve the current console stream.

Next, check out stumpless_add_entry in src/target.c. This is the workhorse function for logging messages, and is a good place to put the logic to handle this option. Get the result from the calls to the sendto functions, and if the result code indicates failure (less than zero) and the option is set on the target, then print the formatted message to the console.

Don't forget to document the option after you implement it in include/stumpless/option.h.

Once you have implemented this, be sure to add a test for the functionality. Test code already exists to make sure that setting and unsetting the option behaves as expected - look for TEST( SetOption, Pid ) in test/function/target.cpp. Use this test as a starting point to create a new test that logs a message before and after setting the option. To cause a failure, you can use a stream target with a read only stream so that attempts to write to it fail. You can see an example of this strategy in the unit test suite for stream targets - look for TEST( StreamTargetWriteTest, ReadOnlyStream ) in test/function/target/stream.cpp. To capture output, set the console stream to your own custom stream using stumpless_set_cons_stream.

format checking of msgid

The syslog RFC (RFC 5424) specifies that a number of fields only include printable ASCII characters (decimal values 33 to 126 inclusive), including the msgid. Checking the characters of supplied msgid arguments will not only help users stay compliant with the standard and provide one point of mitigation for encoding bugs/vulnerabilities.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

There are a number of functions that allow a msgid to be supplied - the constructor for entries, the set feature for the msgid of entries, and the default msgid setting for targets, to list a few. Since this check will need to take place in several places, you will be best served by implementing it in a single function and then calling it wherever required.

Declare your new function in include/private/entry.h, and define it in src/entry.c. After it has been defined, add calls to it wherever a msgid is passed as a parameter in the library, which are the following functions:

  • vstumpless_new_entry (in src/entry.c)
  • stumpless_set_entry_msgid (in src/entry.c)
  • stumpless_set_target_default_msgid (in src/target.c)

You will need to add a new error code that can be thrown when an issue is detected. You can find information on the error codes and handling in the appropriate section of the development guide. Name the new error something like 'STUMPLESS_INVALID_ENCODING' so that it can be reused by encoding checks of other values in the future.

Don't forget to add tests for your new functionality! These should go alongside the tests for the functions that have msgids - check test/function/target.cpp and test/function/entry.cpp for existing tests for these functions, and add new tests that make sure that msgids with invalid characters are rejected.

length checking of param names

The syslog RFC (RFC 5424) specifies a maximum length for many fields of a log message, including param names. Checking the length of supplied param name arguments will not only help users stay compliant with the standard, but will also allow for efficiencies in the implementation by eventually allowing for the use of fixed-length buffers instead of memory allocated from the heap.

As specified in the RFC, param names should be checked for their length and rejected if they are more than the allowed length (32 characters). Note that this length does not include the terminating NULL character from the C string representation.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

There are a number of functions that allow parameter name to be supplied - the constructor for params, and the functions that allow new params to be added to elements and entries directly. Since this check will need to take place in several places, you will be best served by implementing it in a single function and then calling it wherever required.

Declare your new function (something like validate_param_name_length) in include/private/validate.h, and define it in src/validate.c. Similar validation functions have already been created for msgids and app names - use them as a reference as needed. After your new function has been defined, add calls to it wherever a param name is passed as a parameter in the library, which are the following functions:

  • stumpless_new_param (in src/param.c)
  • stumpless_set_param_name (also in src/param.c)
  • stumpless_add_new_param (in src/element.c)
  • stumpless_add_new_param_to_entry (in src/entry.c)

Note that you don't need to validate names passed to search functions like stumpless_get_param_by_name as the search will simply fail for non-compliant names.

Update the documentation for each of these functions to specify that the param name length is restricted to be 32 characters or less. The relevant documentation is in a doxygen comment format in the include files corresponding to the source files (include/stumpless/param.h, include/stumpless/element.h, and include/stumpless/entry.h). Add the note about this to the @param descriptions of the param name parameters.

An error already exists that should be used for invalid param names: STUMPLESS_ARGUMENT_TOO_BIG. Raise this error in your validation function if a param name that is too long is detected, using the raise_argument_too_big function from src/error.c. Again, the existing validation functions for msgids and app names are good references to look at.

Don't forget to add tests for your new functionality! These should go alongside the tests for the functions that have param names - check test/function/param.cpp, test/function/element.cpp, and test/function/entry.cpp for existing tests for these functions, and add new tests that make sure that param names that are too long are rejected.

implement param to string method

It is often useful to be able to obtain out a string representation of a given value either for user interface hints, troubleshooting, or operations like value comparison. Such a function is currently implemented for some stumpless data types (like the version struct) but not for others, including the param struct.

Note that this function is not intended for use in the formatting of a log message as this output may be subtly different, for example when escape codes are needed. Rather, it is meant to give an as-is represenation of the param itself (name and value).

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

First, read this specific section of the development guide devoted to adding new functions. It provides an outline of the work you will need to do beyond the implementation and testing of the function.

Next, add a declaration for your function in the include/stumpless/param.h header file. Name the function stumpless_param_to_string and document its behavior in the same doxygen format as the others in the same header. Make sure to cover the following points:

  • the general format of the output (suggested: <name>: <value>)
  • the supplied argument should be a const pointer
  • explicitly state that the result must be freed when it is no longer needed

Now you are ready to add the matching implementation for the function in src/param.c. Use the code for existing functions in this file as examples. Be sure to use the length measurements already available in the struct to avoid any strlen calls when determining the size of the memory to allocate. Also avoid expensive operations like sprintf - this is doable using simple memcpy calls and assignments.

Finally, be sure to add tests for the new function. These should go in test/function/param.cpp and should achieve full coverage, including for memory allocation failure and NULL argument cases. Again, there are already similar test cases for other functions in this file that you can look at to get a general idea of how the tests should be structured.

current target will be invalid after it is closed

The current target is set to to the last opened target, or it can be manually set by the user using the stumpless_set_current_target function. However, if this target is closed the current target pointer is not changed, and will still point to the invalid memory.

The target closure functions need to be updated to reset the current target. It would make the most sense to set the current target to the default target when this happens. The simplest way to do this would be to add a private function to src/target.c that resets the current target, and then call this from each target closure function.

Tests can simply open a target, make sure it is the current target, and then close the target and make sure that the current target is no longer a pointer to the closed target.

The new behavior of the current target should be added to the documentation - it would make the most sense to add it to the stumpless_get_current_target function documentation.

check italian (it-IT) localization

Localization for Italian was added in #155 by the library's main author (@goatshriek). However, the author's command of the Italian language is not very strong, and as such the translations should be checked for accuracy and general correctness.

This is a straightforward review - simply look at include/private/config/locale/it-it.h and submit a pull request with updates and corrections.

format checking of app-name

The syslog RFC (RFC 5424) specifies that a number of fields only include printable ASCII characters (decimal values 33 to 126 inclusive), including the app-name. Checking the characters of supplied app-name arguments will not only help users stay compliant with the standard, but will also provide a point of mitigation for encoding bugs and vulnerabilities.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block.

There are a number of functions that allow an app-name to be supplied - the constructor for entries, the set feature for the app-name of entries, and the default app-name setting for targets. Since this check will need to take place in several places, you will be best served by calling a single function wherever required.

But good news: a function that does this already exists! It is in src/validate.c and is named validate_msgid_format. You just need to do some refactoring of this function to make it more generalized to support app-names (and other fields in the future). This amounts to renaming the function to something more general (perhaps validate_printable_ascii?) and changing invocations of it to this new name. An easy approach to take here is to rename the definition and declaration, and then follow the resulting compile errors to find the invocations. Or do a grep! Or some other find/replace method, it is up to you.

After this refactoring, add calls to the function wherever an app-name is passed as a parameter in the library, which are the following functions:

  • vstumpless_new_entry (in src/entry.c)
  • stumpless_set_entry_app_name (in src/entry.c)
  • stumpless_set_target_default_app_name (in src/target.c)

Update the documentation for each of these functions to specify that the app name is restricted to specific characters. The relevant documentation is in a doxygen comment format in the include files corresponding to the source files (include/stumpless/entry.h and include/stumpless/target.h). Add the note about this to the @param descriptions of the app-name parameters.

Don't forget to add tests for your new functionality! These should go alongside the tests for the functions that have app-names - check test/function/target.cpp and test/function/entry.cpp for existing tests for these functions, and add new tests that make sure that app-names with invalid characters are rejected.

implement ODELAY option

Stumpless currently does not support the STUMPLESS_OPTION_ODELAY option despite providing it in its header files. This option is meant to mirror the LOG_ODELAY option in functionality. The meaning will change depending on the target - each target will need to be evaluated to make sure that it conforms to this default setting.

Don't forget to document the option after you implement it in include/stumpless/option.h.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

automatic meta element

RFC 5424 specifies that a meta structured data element should be included to give some level of information about the log message itself. Stumpless should have the ability to generate this element automatically, as well as the capability to include it automatically when logging to given targets.

implement NOWAIT option

Stumpless currently does not support the STUMPLESS_OPTION_NOWAIT option despite providing it in its header files. This option is meant to mirror the LOG_NOWAIT option in functionality, and should be straightforward to implement as stumpless does not currently spawn any child processes during logging. If no work is actually required to implement, then this will simply amount to a documentation exercise.

Don't forget to document the option after you implement it in include/stumpless/option.h.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

unsafe multithreaded writes in PERROR option

As noted by @Jk-bit in the community Gitter, the output generated by the STUMPLESS_OPTION_PERROR option on targets writes to the error stream without any sort of multithreading protection, which could potentionally lead to issues. These writes should be protected by the error_stream_free mutex in src/error.c that is used for stumpless_perror already.

automatic time quality element

RFC 5424 specifies that a timeQuality structured data element should be included to give level of confidence information around the timestamp field. Stumpless should have the ability to generate this element automatically, as well as the capability to include it automatically when logging to given targets such as network ones.

implement spanish (es-ES) localization

Localization has been added to the library, and Spanish (es-ES) has since been added with stub values. However, these messages are not useful and need to be replaced with actual Spanish to be of any use.

This will be straightforward for someone that speaks the language, even if you have very little knowledge of C. You will simply need to update the strings in include/private/config/locale/es-es.h with Spanish strings (in UTF-8 encoding). If you want to see what the English message is, check the corresponding values in include/private/config/locale/en-us.h.

length checking of the msgid

The syslog RFC (RFC 5424) specifies a given length for many fields of a log message, including the msgid. Checking the length of supplied msgid arguments will not only help users stay compliant with the standard, but will also allow for efficiencies in the implementation by eventually allowing for the use of fixed-length buffers instead of memory allocated on the heap.

As specified in the RFC, msgid parameters should be checked for their length and rejected if they are more than the allowed length (32 characters). Note that this length does not include the terminating NULL character from the C string representation.

Check out the Contributing Guidelines and the development guide for the basics on working with stumpless and submitting changes.

General Approach

There are a few details left out of the following approach, for you to fill in as you encounter them. If you find you need help, please ask here or on the project gitter and someone can help you get past the stumbling block. You are also free to take a different approach if you feel it is better - this is merely meant as a starting point.

There are a number of functions that allow a msgid to be supplied - the constructor for entries, the set feature for the msgid of entries, and the default msgid setting for targets, to list a few. Since this check will need to take place in several places, you will be best served by implementing it in a single function and then calling it wherever required.

Declare your new function (something like validate_msgid_length) in include/private/validate.h, and define it in src/validate.c. You will need to create the latter of these files - don't forget to add it to the source file list STUMPLESS_SOURCES in CMakeLists.txt. After it has been defined, add calls to it wherever a msgid is passed as a parameter in the library, which are the following functions:

  • vstumpless_new_entry (in src/entry.c)
  • stumpless_set_entry_msgid (in src/entry.c)
  • stumpless_set_target_default_msgid (in src/target.c)

An error already exists that should be used for invalid message ids: STUMPLESS_ARGUMENT_TOO_BIG. Raise this error in your validation function if a msgid that is too long is detected, using the raise_argument_too_big function from src/error.c.

Don't forget to add tests for your new functionality! These should go alongside the tests for the functions that have msgids - check test/function/target.cpp and test/function/entry.cpp for existing tests for these functions, and add new tests that make sure that msgids that are too long are rejected.

build fails in cygwin

Short description of Problem

Attempting to build stumpless in a cygwin environment with the required packages fails.

Environment Description

This has been tested in a Windows 10 build 10240 with cygwin64 3.1.2.

Other details

Current problems with this build appear to come primarily from conflicting type definitions between standard Unix headers (sys/socket.h, unistd.h) and the Windows headers (windows.h, winsock2.h). These are both detected by cmake, and when the library is compiled with both headers conflicting type definitions emerge. Disabling socket and network targets does not alleviate the issue.

Some other smaller problems also arise with Windows functionality and gtest, which should be easier to work around.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.