Custom Log4Net appender to push log messages to a Redis Stream. Written for .Net Core applications
<TargetFramework>netstandard2.0</TargetFramework>
Redis 5.0 introduced Redis Streams, an append only log like data structure. This paradigm is a natural fit for application logging, so a common logging framework, Log4Net, was extended through a custom appender to provide the functionality.
This readme will provide detail on the how the appender should be leveraged to communicate with Redis Streams.
Available on Nuget.
For Microsoft .Net Core applications An accessible Redis instance >= v5.0.
Docker is not required to run the example application, however a Dockerfile and docker-compose.yml file are included to maintain a consistent environment.
To run a remote instance of Redis for tests, review the Redis Docker container.
The following Log4Net details must be incorporated to provide the necessary configuration.
<log4net>
<logger name="DefaultLogger">
<level value="ALL" />
<appender-ref ref="RedisStreamAppender" />
</logger>
<appender
name="RedisStreamAppender"
type="Log4Net.RedisStream.RedisStreamAppender, Log4Net.RedisStream">
<!-- required parameters -->
<RedisConnectionString value="redis:6379" />
<RedisStreamName value="ExampleAppStream" />
<!-- optional parameters -->
<RedisStreamMessageField value="message" />
<threshold value="INFO" />
<!-- layout -->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
</log4net>
The appender configuration leverages three primary settings.
- RedisConnectionString - Required - Connection string to the Redis instance
- RedisStreamName - Required - The Redis Stream where log entries for this appender will be written
- RedisStreamMessageField - Optional - The name of the field that hosts the log message data within the Redis Stream. By default, it is message.
It is important to note that in this configuration, all log messages up to the INFO subtype are processed. DEBUG logs are not processed.
Docker configuration files are located at the root of the solution.
The Dockerfile creates a Docker log4net-redisstream-example image locally. Use the following command to build the image.
docker build -t log4net-redisstream-example .
Utilize the Docker Compose command to initialize the environment with a Redis instance along side the .NetCore example application. Configurations for Docker Compose are found in the docker-compose.yml. The configuration requires the previously built log4net-redisstream-example image.
docker-compose up
After some initial Redis startup logging, the following should be seen in the Docker console.
console_1 | Log4Net configuration loaded. console_1 | Default logger created. console_1 | Log attempted. console_1 | Redis Stream log example finished. log4netredisstream_console_1 exited with code 0
If Log4Net is correctly configured, the standard logger should automatically forward to the Redis Stream instance. You can test that the number of entries has incremented by using the following command from the Redis cli command:
xlen ExampleAppStream
Note the stream name comes from the configuration
Or review the values with the following command (note this brings back ALL of stream entries):
xrange ExampleAppStream - +
See the Redis Streams documentation for more information.
To ensure that your Redis instance is available, you can use the cli command to PING the instance. If successful, a PONG response is expected.
To clean up the resultant Docker images, containers, and network, use the following command:
docker-compose down
The tests are XUnit unit tests. You can execute the tests, with code coverage analysis, by running:
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput=./lcov.info /p:Exclude=[xunit.*]*
- VSCode - Integrated Development Environment
- Redis - In-memory and persistent data strustures
- StackExchange.Redis - Redis Client
- Log4Net - Base logging framework
- XUnit - Unit test framework
- Docker Compose - Containerization and Orchestation
- @Guarrdon - Problem-solving, technology leader
See also the list of contributors who participated in this project.
This project is licensed under the MIT License - see the LICENSE.md file for details.