Centralized logging hosted in Docker

Proper logging helps to understand a problem with your software, especially during the development of a new product. I’m currently working on a new project where multiple microservices are hosted in separate Docker containers. In this scenario, centralized logging really helps to validate that everything goes as expected. In this blog post, I want to share how to run a logging solution named Seq in a Docker container.

Please note: this blog post will not cover how to integrate logging into your solution. For more information please take a look at the Seq documentation here.

What is Seq?

Seq is a solution that helps you to centralize and structure logging of your solutions.

Modern structured logging bridges the gap between human-friendly text logs, and machine-readable formats like JSON. Using event data from libraries such as Serilog, ASP.NET Core, and Node.js, Seq makes centralized logs easy to read, and easy to filter and correlate, without fragile log parsing.

 

Seq collects data over HTTP, while your applications use the best available structured logging APIs for your platform. The simple Windows installer, and plug-ins from NuGet or NPM, make getting started quick and friction-free.

For more information please visit the Seq website.

Creating the centralized logging container

The installation of Seq is done by a 64 bit MSI based installer. You can download the latest installer from the Seq website. Because Seq is a Windows based solution and is installed with MSIEXEC, the Windows Server Core image is required. Create a Dockerfile and define the Windows Server Core image with the following line.

Next step is to copy the Seq installer in the container. In my case, the Seq MSI is inside the same folder as the Dockerfile.

Start the installation with MSIEXEC and the default parameters. In case something goes wrong we could use the installation logging.

Seq is running as a service and once Seq is installed the registration still needs to take place. This can be done using the SC command. Please note that the start option needs to be on “auto” otherwise the service won’t start.

Because there is no output, I’ve added a little PowerShell loop that will output the process usage to prevent the container from stopping.

You can download the full Dockerfile here.

Now the Dockerfile is complete the container can be build by running the default build command.

Once the Docker image had been created you can list all images using “docker images”.

Now the image has been built you can run it with the following command. Please note: you need to map port 5341 to make it accessible from the outside.

Once the container is up and running you can reach it on the mapped port. This way you should be able to collect logs from different processes during development.

Please note: When running Docker on the same machine as your development environment you cannot access the container by hostname. You’ll need to use the IP address instead. To get the correct IP address use the “docker inspect [container id]” command.

Composing Seq with other Docker containers

Once your solutions are also running within a container you’ll need to link the individual containers to enable internal interaction. This can be done using a docker-compose file as shown below.

In order to make communication possible, you need to link the microservices to the Seq container. This can be done by using the link option within the docker-compose file.

You can download the full docker-compose file here.

Now within the ms1 and ms2 container, Seq can be resolved by using the hostname seq. So within your solution, the report URL should be http://seq:5341.

In order to start all containers use the following command.

Once the containers are up you will notice that the microservices are logging to Seq.

Conclusion

Logging is very important, especially when you need to troubleshoot an issue. Using a solution like Seq can really help with centralizing all logging of multiple solutions and structuring the logs. When using Docker you can run Seq within a Windows based container so other containers can directly log to Seq. With the docker-compose file, containers can link to each other and everything will be logged. As this solution is currently very useful for my colleague and me and I hope also for you. If you have any comments or questions please leave them below.

 

 

  • Nicholas Blumhardt

    Thanks for the great write-up. I love how easy Compose makes the DNS/configuration 🙂

    Would it be an improvement to execute Seq’s run command without having the service installed? E.g. instead of the RUN sc and CMD directives, just use:

    The result should be pretty similar, but with the advantage that Seq’s own diagnostic output will be on STDOUT.

    The other Seq Dockerfile I’ve used also installs the service, but perhaps I should give this technique a try… Just a thought!

    • Thanks for the great feedback!

      I tried to run it like you suggested but end up with the following response.

      The filename, directory name, or volume label syntax is incorrect.

      I did not had the time to troubleshoot this issue so came up with the solution in the blog post.

    • Nicholas Blumhardt

      Interesting, thanks for the follow-up. I’ll check it out when I have a chance! 🙂