| <configuration> | |
| <!-- Context properties --> | |
| <springProperty scope="context" name="appName" source="spring.application.name" defaultValue="research-platform"/> | |
| <springProperty scope="context" name="appEnv" source="spring.profiles.active" defaultValue="dev"/> | |
| <springProperty scope="context" name="instanceId" source="instance.id" defaultValue="local"/> | |
| <!-- Console Appender (Human-readable) --> | |
| <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> | |
| <encoder> | |
| <pattern>%d{ISO8601} %highlight(%-5level) [%thread] [%X{traceId:-},%X{spanId:-}] %logger{36} - %msg%n</pattern> | |
| </encoder> | |
| </appender> | |
| <!-- JSON Structured Logging Appender --> | |
| <appender name="JSON_APPENDER" class="ch.qos.logback.core.ConsoleAppender"> | |
| <encoder class="net.logstash.logback.encoder.LogstashEncoder"> | |
| <fieldNames> | |
| <timestamp>@timestamp</timestamp> | |
| <message>message</message> | |
| <logger>log.logger</logger> | |
| <thread>process.thread.name</thread> | |
| <level>log.level</level> | |
| <levelValue>[ignore]</levelValue> | |
| <version>[ignore]</version> | |
| <mdc>mdc</mdc> | |
| </fieldNames> | |
| <customFields>{"service.name":"${appName}","service.environment":"${appEnv}","instance.id":"${instanceId}","ecs.version":"8.11"}</customFields> | |
| <includeMdc>true</includeMdc> | |
| </encoder> | |
| </appender> | |
| <!-- Loki Logback Appender --> | |
| <appender name="LOKI" class="com.github.loki4j.logback.Loki4jAppender"> | |
| <http> | |
| <url>http://localhost:3100/loki/api/v1/push</url> | |
| <connectTimeoutMs>10000</connectTimeoutMs> | |
| <requestTimeoutMs>30000</requestTimeoutMs> | |
| </http> | |
| <format> | |
| <label> | |
| <pattern>app=${appName},host=${HOSTNAME},level=%level,traceId=%X{traceId:-none},spanId=%X{spanId:-none}</pattern> | |
| <readMarkers>true</readMarkers> | |
| </label> | |
| <message> | |
| <pattern> | |
| { | |
| "@timestamp": "%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ}", | |
| "level": "%level", | |
| "logger": "%logger{36}", | |
| "thread": "%thread", | |
| "traceId": "%X{traceId:-}", | |
| "spanId": "%X{spanId:-}", | |
| "message": "%message", | |
| "exception": "%ex{short}" | |
| } | |
| </pattern> | |
| </message> | |
| <sortByTime>true</sortByTime> | |
| </format> | |
| <batch> | |
| <maxItems>1000</maxItems> | |
| <maxBytes>102400</maxBytes> | |
| <timeoutMs>1000</timeoutMs> | |
| </batch> | |
| <buffer> | |
| <maxItems>50000</maxItems> | |
| <fullCallback>DISCARD</fullCallback> | |
| </buffer> | |
| </appender> | |
| <!-- OpenTelemetry Log Appender --> | |
| <appender name="OTEL" class="io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender"> | |
| <captureExperimentalAttributes>true</captureExperimentalAttributes> | |
| <captureCodeAttributes>true</captureCodeAttributes> | |
| <captureMarkerAttribute>true</captureMarkerAttribute> | |
| </appender> | |
| <!-- File Appender for Audit Logs --> | |
| <appender name="AUDIT_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |
| <file>logs/audit.log</file> | |
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |
| <fileNamePattern>logs/audit-%d{yyyy-MM-dd}.log</fileNamePattern> | |
| <maxHistory>90</maxHistory> | |
| </rollingPolicy> | |
| <encoder class="net.logstash.logback.encoder.LogstashEncoder"> | |
| <fieldNames> | |
| <timestamp>@timestamp</timestamp> | |
| <message>message</message> | |
| </fieldNames> | |
| </encoder> | |
| </appender> | |
| <!-- Async wrapper for performance --> | |
| <appender name="ASYNC_JSON" class="ch.qos.logback.classic.AsyncAppender"> | |
| <queueSize>10000</queueSize> | |
| <discardingThreshold>0</discardingThreshold> | |
| <neverBlock>true</neverBlock> | |
| <includeCallerData>false</includeCallerData> | |
| <appender-ref ref="JSON_APPENDER"/> | |
| </appender> | |
| <appender name="ASYNC_LOKI" class="ch.qos.logback.classic.AsyncAppender"> | |
| <queueSize>5000</queueSize> | |
| <discardingThreshold>0</discardingThreshold> | |
| <neverBlock>true</neverBlock> | |
| <appender-ref ref="LOKI"/> | |
| </appender> | |
| <!-- Root Logger --> | |
| <root level="INFO"> | |
| <appender-ref ref="CONSOLE"/> | |
| <appender-ref ref="ASYNC_JSON"/> | |
| <appender-ref ref="ASYNC_LOKI"/> | |
| <appender-ref ref="OTEL"/> | |
| </root> | |
| <!-- Audit Logger --> | |
| <logger name="AUDIT_LOGGER" level="INFO" additivity="false"> | |
| <appender-ref ref="AUDIT_FILE"/> | |
| <appender-ref ref="ASYNC_JSON"/> | |
| </logger> | |
| <!-- OpenTelemetry Logs --> | |
| <logger name="io.opentelemetry" level="WARN"/> | |
| <logger name="org.apache.kafka" level="WARN"/> | |
| <logger name="org.springframework.boot.actuate" level="INFO"/> | |
| <!-- Development profile --> | |
| <springProfile name="dev"> | |
| <root level="DEBUG"> | |
| <appender-ref ref="CONSOLE"/> | |
| </root> | |
| </springProfile> | |
| <!-- Production profile --> | |
| <springProfile name="production"> | |
| <root level="INFO"> | |
| <appender-ref ref="ASYNC_JSON"/> | |
| <appender-ref ref="ASYNC_LOKI"/> | |
| <appender-ref ref="OTEL"/> | |
| </root> | |
| </springProfile> | |
| </configuration> | |
| <!-- src/main/resources/logback-spring.xml --> | |
| <configuration> | |
| <springProperty scope="context" name="appName" source="spring.application.name" defaultValue="research-platform"/> | |
| <springProperty scope="context" name="appEnv" source="spring.profiles.active" defaultValue="dev"/> | |
| <springProperty scope="context" name="instanceId" source="instance.id" defaultValue="local"/> | |
| <!-- Console Appender (Human-readable) --> | |
| <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> | |
| <encoder> | |
| <pattern>%d{ISO8601} %highlight(%-5level) [%thread] [%X{traceId:-},%X{spanId:-}] %logger{36} - %msg%n</pattern> | |
| </encoder> | |
| </appender> | |
| <!-- JSON Structured Logging Appender --> | |
| <appender name="JSON_APPENDER" class="ch.qos.logback.core.ConsoleAppender"> | |
| <encoder class="net.logstash.logback.encoder.LogstashEncoder"> | |
| <fieldNames> | |
| <timestamp>@timestamp</timestamp> | |
| <message>message</message> | |
| <logger>log.logger</logger> | |
| <thread>process.thread.name</thread> | |
| <level>log.level</level> | |
| </fieldNames> | |
| <customFields>{"service.name":"${appName}","service.environment":"${appEnv}","ecs.version":"8.11"}</customFields> | |
| <includeMdc>true</includeMdc> | |
| </encoder> | |
| </appender> | |
| <!-- Loki Logback Appender --> | |
| <appender name="LOKI" class="com.github.loki4j.logback.Loki4jAppender"> | |
| <http> | |
| <url>http://localhost:3100/loki/api/v1/push</url> | |
| <connectTimeoutMs>10000</connectTimeoutMs> | |
| <requestTimeoutMs>30000</requestTimeoutMs> | |
| </http> | |
| <format> | |
| <label> | |
| <pattern>app=${appName},host=${HOSTNAME},level=%level,traceId=%X{traceId:-none}</pattern> | |
| </label> | |
| <message> | |
| <pattern> | |
| { | |
| "@timestamp": "%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ}", | |
| "level": "%level", | |
| "logger": "%logger{36}", | |
| "traceId": "%X{traceId:-}", | |
| "spanId": "%X{spanId:-}", | |
| "message": "%message" | |
| } | |
| </pattern> | |
| </message> | |
| <sortByTime>true</sortByTime> | |
| </format> | |
| <batch> | |
| <maxItems>1000</maxItems> | |
| <maxBytes>102400</maxBytes> | |
| <timeoutMs>1000</timeoutMs> | |
| </batch> | |
| </appender> | |
| <!-- Audit File Appender --> | |
| <appender name="AUDIT_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |
| <file>logs/audit.log</file> | |
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |
| <fileNamePattern>logs/audit-%d{yyyy-MM-dd}.log</fileNamePattern> | |
| <maxHistory>90</maxHistory> | |
| </rollingPolicy> | |
| <encoder> | |
| <pattern>%d{ISO8601} %-5level [%thread] %logger{36} - %msg%n</pattern> | |
| </encoder> | |
| </appender> | |
| <!-- Async Wrappers --> | |
| <appender name="ASYNC_JSON" class="ch.qos.logback.classic.AsyncAppender"> | |
| <queueSize>10000</queueSize> | |
| <discardingThreshold>0</discardingThreshold> | |
| <neverBlock>true</neverBlock> | |
| <appender-ref ref="JSON_APPENDER"/> | |
| </appender> | |
| <appender name="ASYNC_LOKI" class="ch.qos.logback.classic.AsyncAppender"> | |
| <queueSize>5000</queueSize> | |
| <discardingThreshold>0</discardingThreshold> | |
| <neverBlock>true</neverBlock> | |
| <appender-ref ref="LOKI"/> | |
| </appender> | |
| <!-- Root Logger --> | |
| <root level="INFO"> | |
| <appender-ref ref="CONSOLE"/> | |
| <appender-ref ref="ASYNC_JSON"/> | |
| <appender-ref ref="ASYNC_LOKI"/> | |
| </root> | |
| <!-- Audit Logger --> | |
| <logger name="AUDIT_LOGGER" level="INFO" additivity="false"> | |
| <appender-ref ref="AUDIT_FILE"/> | |
| <appender-ref ref="ASYNC_JSON"/> | |
| </logger> | |
| <!-- Development Profile --> | |
| <springProfile name="dev"> | |
| <root level="DEBUG"> | |
| <appender-ref ref="CONSOLE"/> | |
| </root> | |
| </springProfile> | |
| <!-- Production Profile --> | |
| <springProfile name="production"> | |
| <root level="INFO"> | |
| <appender-ref ref="ASYNC_JSON"/> | |
| <appender-ref ref="ASYNC_LOKI"/> | |
| </root> | |
| </springProfile> | |
| </configuration> |
Xet Storage Details
- Size:
- 10.1 kB
- Xet hash:
- 0b635c15b458f5643e1007de88e4807012e193108d418f116cd14089f1bce874
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.