Configuration KARNAK logs
KARNAK offers the possibility of injecting your own log configuration.
The logging system used by KARNAK is logback. For more details on logback, it provides a manual
Variables
Some variables are available and can be used in the logback file.
issuerOfPatientID
are the issuer of patient ID before the deidentificationPatientID
are the patient ID before the deidentificationSOPInstanceUID
are the SOPInstanceUID before the deidentificationDeidentifySOPInstanceUID
are the SOPInstanceUID after the deidentificationSeriesInstanceUID
are the SeriesInstanceUID before the deidentificationDeidentifySeriesInstanceUID
are the SeriesInstanceUID after the deidentificationProjectName
are the project name used for the deidentificationProfileName
are the profile name used for the deidentificationProfileCodenames
are a list of concatenated profile items that has been used for the deidentification
Inject the logback configuration file
By using docker
You must set the environment variable LOGBACK_CONFIGURATION_FILE
with the path of Logback file configuration, it will override the default log file.
For example, if you create your own configuration with the file name my-logback.xml
at the root of the docker-compose.yml.
You must create a volume that will copy the file in the KARNAK docker and define the environment variable LOGBACK_CONFIGURATION_FILE
with the path of the file in the docker container.
services:
karnak:
container_name: karnak
image: osirixfoundation/karnak:v0.9.7
volumes:
- ./my-logback.yml:/logs/my-logback.xml
environment:
LOGBACK_CONFIGURATION_FILE: /logs/my-logback.xml
By using JAVA
If you use directly the KARNAK jar, you must add the following parameter at the startup:
-Dlogging.config=my-logback.xml
Default logback file
The default logback file (see below) has two modes.
Dev Mode
- The variable
ENVIRONMENT
must be set toDEV
to be activate. - Log everything at the
INFO
level except for the packageorg.karnak
andorg.weasis
, they are at theDEBUG
level.
Production Mode
- Always activate, except if the variable
ENVIRONMENT
is set toDEV
. - Logs everything at the
WARN
level - Writes all.log file, it contains:
- Every
WARN
level log org.weasis
INFO
level logorg.karnak
INFO
level log, excepted clinical log
- Every
- Writes clinical.log, it contains:
- Every log with the marker
CLINICAL
which concerns the deidentification
- Every log with the marker
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOGS" value="logs" />
<!--
DEV LOGS
Condition to verify if "ENVIRONMENT" is "DEV"
-->
<if condition='property("ENVIRONMENT").contains("DEV")'>
<then>
<!--
How the logs will be displayed in the standard output (console)
SOPInstanceUID, issuerOfPatientID and PatientID are variables to associate the current DICOM with the log
-->
<appender name="DEV_OUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<Pattern>%black(%d{ISO8601}) %highlight(%-5level) %marker %highlight(%X{SOPInstanceUID}) %highlight(%X{issuerOfPatientID}) %highlight(%X{PatientID}) [%yellow(%t)] %yellow(%C{1.}): %msg%n%throwable</Pattern>
</encoder>
</appender>
<!--
Log everything at the INFO level except for the package org.karnak and org.weasis, they are at the DEBUG level.
-->
<root level="info">
<appender-ref ref="DEV_OUT" />
</root>
<logger name="org.weasis" level="debug" />
<logger name="org.karnak" level="debug" />
</then>
<!--
PRODUCTION LOGS
-->
<else>
<!--
How the warning logs will be displayed in the standard output (console)
SOPInstanceUID, issuerOfPatientID and PatientID are variables to associate the current DICOM with the log
-->
<appender name="WARNING_OUT" class="ch.qos.logback.core.ConsoleAppender">
<!--
Log only at WARN level
-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
<encoder>
<Pattern>%black(%d{ISO8601}) %highlight(%-5level) %marker %highlight(%X{SOPInstanceUID}) %highlight(%X{issuerOfPatientID}) %highlight(%X{PatientID}) [%yellow(%t)] %yellow(%C{1.}): %msg%n%throwable </Pattern>
</encoder>
</appender>
<!--
Write all.log file in the file system.
-->
<appender name="ALL_LOGS" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS}/all/all.log</file>
<!--
Window rolling policy defined by the variable KARNAK_LOGS_MIN_INDEX or KARNAK_LOGS_MAX_INDEX
By default the min is 1 and the max is 10
-->
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>${LOGS}/all/all_%i.log</fileNamePattern>
<minIndex>${KARNAK_LOGS_MIN_INDEX:-1}</minIndex>
<maxIndex>${KARNAK_LOGS_MAX_INDEX:-10}</maxIndex>
</rollingPolicy>
<!--
Size rolling policy defined by the variable KARNAK_LOGS_MAX_FILE_SIZE
By default the max file size is 50MB
-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>${KARNAK_LOGS_MAX_FILE_SIZE:-50MB}</maxFileSize>
</triggeringPolicy>
<!--
Filter not to write logs with the clinical marker
-->
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
<marker>CLINICAL</marker>
</evaluator>
<onMismatch>NEUTRAL</onMismatch>
<onMatch>DENY</onMatch>
</filter>
<encoder>
<pattern>%d %-5level %m%n</pattern>
</encoder>
</appender>
<!--
Write clinical.log file in the file system.
Will contains only the logs with the CLINICAL marker. The logs with CLINICAL marker concerns the information about the deidentification.
Variables used for the CLINICAL log:
SOPInstanceUID, DeidentifySOPInstanceUID, SeriesInstanceUID, DeidentifySeriesInstanceUID, ProjectName, ProfileName, ProfileCodenames
-->
<appender name="CLINICAL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS}/Clinical/clinical.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>${LOGS}/Clinical/clinical_%i.log</fileNamePattern>
<minIndex>${KARNAK_CLINICAL_LOGS_MIN_INDEX:-1}</minIndex>
<maxIndex>${KARNAK_CLINICAL_LOGS_MAX_INDEX:-10}</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>${KARNAK_CLINICAL_LOGS_MAX_FILE_SIZE:-50MB}</maxFileSize>
</triggeringPolicy>
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
<marker>CLINICAL</marker>
</evaluator>
<onMismatch>DENY</onMismatch>
<onMatch>NEUTRAL</onMatch>
</filter>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d SOPInstanceUID_OLD=%X{SOPInstanceUID} SOPInstanceUID_NEW=%X{DeidentifySOPInstanceUID} SeriesInstanceUID_OLD=%X{SeriesInstanceUID} SeriesInstanceUID_NEW=%X{DeidentifySeriesInstanceUID} ProjectName=%X{ProjectName} ProfileName=%X{ProfileName} ProfileCodenames=%X{ProfileCodenames}</Pattern>
</encoder>
</appender>
<!--
Log everything at the WARN level except for the package org.karnak and org.weasis, they are at the INFO level.
The INFO logs won't appear in the standard output, because they will be filtered by the WARNING_OUT appender
-->
<root level="warn">
<appender-ref ref="ALL_LOGS" />
<appender-ref ref="CLINICAL_FILE" />
<appender-ref ref="WARNING_OUT" />
</root>
<logger name="org.weasis" level="info" />
<logger name="org.karnak" level="info" />
</else>
</if>
</configuration>