How to configure file target in nlog.config

Hi,

I’m trying to containerize a windows application that uses Nlog for logging. The app writes to file targets. Here is part of the nlog.config for the application. Please note the fileName parameter. That resolves to C:\Users\Public\Documents\xxxxxxxx\xxxxxxxx\Logs on the local hard drive.

What I want to know is how to specify the file path for a containerized application in my nlog.config. I have a docker compose yml file that defines volumes. I have a decent understanding of how volumes work. But, I don’t know what to put in my nlog.config for the fileName parameter. I would like to write to the app_data volume.

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <extensions>
    <add assembly="DotnetUtils"/>
  </extensions>
  <targets async="true">
    <target name="con" xsi:type="Console"
        layout="${level} - ${message}${onexception:inner=${newline}${literal:text=  Exception\: }${exception:format=Message})}" />
    <target name="file" xsi:type="File" encoding="utf-8"
        fileName="${specialfolder:folder=CommonDocuments:file=xxxxxxxx/xxxxxxxx/Logs/xxxxxxxx.log}"
        archiveFileName="${specialfolder:folder=CommonDocuments:file=xxxxxxxx/xxxxxxxx /Logs/xxxxxxxxr}.{#}.log"
        layout="${longdate:universalTime=True} ${level} ${threadid} ${message} ${onexception:${newline}${exception:format=Message,StackTrace:maxInnerExceptionLevel=4:innerFormat=Message,StackTrace}}"
        createDirs="true" deleteOldFileOnStartup="false"
        archiveEvery="Day" maxArchiveFiles="9" archiveAboveSize="67108864" archiveNumbering="Rolling"
        concurrentWrites="false" enableFileDelete="true" keepFileOpen="false" autoFlush="true" />
services:
  web_api:
    container_name: xxxxxxxx_api_app
    build: .
    ports:
      - 8080:8080
    volumes:
      - app_data:/var/logs
    depends_on:
      - "db"
  db:
    image: postgres
    container_name: postgres_db
    ports:
      - 5432:5432
    environment:
      POSTGRES_PASSWORD: xxxxxxxx
      POSTGRES_HOST: db
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:
  app_data:

The mount point which is on the left side of the colon in the volume mapping definition. But I don’t think Windows containers would have /var/logs that is a Linux path and you already shared the path would be

C:\Users\Public\Documents\xxxxxxxx\xxxxxxxx\Logs 

so that is what you need to configure in anything that runs in the container and that is where you need to mount the volume.

Well that turned out to be easy but took some time to figure out. Screen print:

services:
  web_api:
    container_name: persons_api_app
    build: .
    ports:
      - 8080:8080
    volumes:
      - app_data_nlog_internal:/var/nlog/internal
      - app_data_nlog_application:/var/nlog/application
    depends_on:
      - "db"
  db:
    image: postgres
    container_name: postgres_db
    ports:
      - 5432:5432
    environment:
      POSTGRES_PASSWORD: xxxxxxxx
      POSTGRES_HOST: db
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:
  app_data_nlog_internal:
  app_data_nlog_application:
<?xml version="1.0" encoding="utf-8"?>
<nlog
  xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  autoReload="true"
  internalLogLevel="Trace"
  internalLogFile="/var/nlog/internal/internallog.log"
  throwConfigExceptions="true">
  <targets>
    <target
      xsi:type="File"
      name="logfile"
      fileName="/var/nlog/application/nlog-${date:format=yyyy-MM-dd}.log"
      archiveFileName="/var/nlog/application/nlog-{date:format=yyyy-MM-dd}.{#}.log"
      layout="${longdate:universalTime=True} ${level} ${threadid} ${message} ${onexception:${newline}${exception:format=Message,StackTrace:maxInnerExceptionLevel=4:innerFormat=Message,StackTrace}}"
      createDirs="true"
      deleteOldFileOnStartup="false"
      archiveEvery="Day"
      maxArchiveFiles="9"
      archiveAboveSize="67108864"
      archiveNumbering="Rolling"
      concurrentWrites="false"
      enableFileDelete="true"
      keepFileOpen="false"
      autoFlush="true" />
    <target
      xsi:type="Console"
      name="logconsole" />
  </targets>
  <rules>
    <logger name="*" minlevel="Trace" writeTo="logconsole,logfile" />
  </rules>
</nlog>

Well, since you started the topic with

I assumed Windows containers as Windows applications would not run in a Linux container, but it looks like yoou are using Linux containers

Yeah, the Postgres image is most likely based on a Linux image.

I also have a task to create a windows container but then run the Postgres windows installer within the container. That will be interesting too and probably a little bit easier for me.