Erelephant
Erelephant

Reputation: 161

Access a log file generated by .NET Core Console Application inside Docker

I'm completely new to the Docker world and no matter where ever I searched for it, it seems like there's no applicable solution. I know many questions asks about the same issue surrounding logging, yet I could not find a basic, detailed solution that will help me to apply it myself.

tldr;

I currently have a .NET Core 5.0 Console Application that creates a log file using log4net to a local directory. I want to transfer the application to run through a Windows-based docker container and to access the log file while/after it ran to see its results.

I saw the docker documentation | volumes yet could not understand how is it possible to define and later on access the log file.

Is this the way to do it? what should I define differently on my application?

Upvotes: 2

Views: 1610

Answers (2)

Mark Dornian
Mark Dornian

Reputation: 416

I wanted to expand on Michal Rosenbaum's answer. This configuration will write all my logs to \application-logs within the container and to C:/application-logs/myProject on my host machine.

If you are using .NET Core, you can define the volume in the DockerFile as follows:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
VOLUME "/application-logs"
WORKDIR /app
EXPOSE 80
EXPOSE 443

You can define the mount in the launchSettings.json in the Docker profile using the DockerfileRunArguments property like this

    "Docker": {
      "commandName": "Docker",
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
      "environmentVariables": {
        "ASPNETCORE_URLS": "https://+:443;http://+:80",
        "PROFILE": "DOCKER"
      },
      "publishAllPorts": true,
      "useSSL": true,
      "httpPort": 32003,
      "sslPort": 32103,
      "DockerfileRunArguments": "-v c:\\application-logs\\myProject:/application-logs"
    }

My log4net.config file looks like this. The only important node here for this discussion is File.

<log4net>
  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="/application-logs/myProject-" />
    <appendToFile value="true" />
    <rollingStyle value="Composite" />
    <datePattern value="yyyy-MM-dd'.txt'" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="10MB" />
    <staticLogFileName value="false" />
    <layout type="Roostr.Logic.Logging.EnhancedFormatter">
      <conversionPattern value="%date %5level %logger.%method [%line] - Message: %message%newline" />
    </layout>
  </appender>
  <root>
    <level value="ALL" />
    <appender-ref ref="RollingLogFileAppender" />
  </root>
</log4net>

Upvotes: 0

Michal Rosenbaum
Michal Rosenbaum

Reputation: 2061

Probably it's not about changing anything in your application, you just need to identify the directory where your logs are stored in the container and attach a volume or bind a mount to it on the host part. So, you can either:

  • Create a volume and during "docker run" associate it with a directory inside the container where your logs are stored. Volumes can be managed using Docker, which makes it a preferred option. By leveraging them you can e.g. type "docker inspect some-volume-name" to find out where in the host's file system you can see the files from the volume, your logs in this case.

  • Make a bind mount, which means you are mapping a directory from a host to a directory in a container. This option is pretty straightforward, but you are losing out on all the volumes' features.

Path with volume

Creating a docker volume.

docker volume create logs-from-net-app

Inspecting the volume to find out where you can find its contents.

docker volume inspect logs-from-net-app

Attaching it to the container.

docker run --mount type=volume,source=logs-from-net-app,target=//c/path/to/logs "hello-world"

Path with mounting bind

Making a bind mount during docker run

docker run --mount type=bind,source=C:\logs,target=//c/path/to/logs "hello-world"

Upvotes: 4

Related Questions