下面是
S3FixedWindowRollingPolicy
类的实现,负责将本地日志文件移动到S3。
S3固定窗口滚动策略
package com.paytmlabs.adtech.logback.policy;
import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
import ch.qos.logback.core.rolling.RolloverFailure;
import ch.qos.logback.core.rolling.helper.FileNamePattern;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.paytmlabs.adtech.domain.common.MarkerType;
import com.paytmlabs.adtech.logback.adapter.AmazonS3Adapter;
import com.paytmlabs.adtech.logback.shutdown.RollingPolicyShutdownListener;
import com.paytmlabs.adtech.logback.shutdown.ShutdownHookType;
import com.paytmlabs.adtech.logback.shutdown.ShutdownHookUtil;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class S3FixedWindowRollingPolicy extends FixedWindowRollingPolicy implements RollingPolicyShutdownListener {
/**
* Constants
*/
private String s3BucketName;
private String s3FolderName;
private MarkerType markerType;
private ShutdownHookType shutdownHookType;
private boolean rolloverOnExit;
private boolean prefixTimestamp;
private boolean prefixIdentifier;
/**
* Dependencies
*/
private TransferManager transferManager;
private AmazonS3Adapter amazonS3Adapter;
// private MetricsService metricsService; // TODO: Inject this dependency
public S3FixedWindowRollingPolicy() {
super();
this.markerType = MarkerType.NONE;
this.rolloverOnExit = false;
this.shutdownHookType = ShutdownHookType.NONE;
this.prefixTimestamp = false;
this.prefixIdentifier = false;
}
@Override
public void start() {
super.start();
amazonS3Adapter = new AmazonS3Adapter(getS3BucketName(), getS3FolderName(), isPrefixTimestamp(), isPrefixIdentifier(), transferManager);
if (isPrefixIdentifier()) {
addInfo("Using identifier prefix \"" + amazonS3Adapter.getIdentifier() + "\"");
}
//Register shutdown hook so the log gets uploaded on shutdown, if needed
ShutdownHookUtil.registerShutdownHook(this, getShutdownHookType());
}
@Override
public void rollover() throws RolloverFailure {
super.rollover();
// meterRegistry.counter(METRIC_LOGS_ROLLOVER, TAG_ACTION, "rollover", TAG_TASK, "UploadFileToS3Async").increment();
// Creating the FileNamePattern
FileNamePattern fileNamePattern = new FileNamePattern(getFileNamePattern(), getContext());
// Upload the current log file into S3
amazonS3Adapter.uploadFileToS3Async(fileNamePattern.convertInt(getMinIndex()), new Date());
}
/**
* Shutdown hook that gets called when exiting the application.
*/
@Override
public void doShutdown() {
if (isRolloverOnExit()) {
//Do rolling and upload the rolled file on exit
// meterRegistry.counter(METRIC_LOGS_ROLLOVER, TAG_ACTION, "do-shutdown", TAG_TASK, "Rollover").increment();
rollover();
} else {
//Upload the active log file without rolling
// meterRegistry.counter(METRIC_LOGS_ROLLOVER, TAG_ACTION, "do-shutdown", TAG_TASK, "UploadFileToS3Async").increment();
amazonS3Adapter.uploadFileToS3Async(getActiveFileName(), new Date(), true);
}
//Wait until finishing the upload
amazonS3Adapter.doShutdown();
}
}
logback-spring.xml
<configuration debug="true" scan="true" scanPeriod="150 seconds">
<appender class="ch.qos.logback.core.ConsoleAppender" name="CONSOLE" target="System.out">
<filter class="com.paytmlabs.adtech.config.filter.ConsoleLogLevelFilter"/>
<encoder>
<Pattern>%d %-4relative [%thread] %-5level %marker %logger{35} - %msg%n</Pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender class="ch.qos.logback.classic.AsyncAppender" name="ASYNC_CONSOLE">
<appender-ref ref="CONSOLE"/>
<neverBlock>true</neverBlock> <!-- default 256 -->
<queueSize>1024</queueSize> <!-- default false, set to true to cause the Appender not block the application and just drop the messages -->
</appender>
<appender class="ch.qos.logback.core.rolling.RollingFileAppender" name="REQUEST">
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%msg%xEx{3}%n</pattern>
</encoder>
<file>logs/request/adtech.dealstrigger.request.${HOSTNAME}.log</file>
<filter class="com.paytmlabs.adtech.config.filter.RequestLogLevelFilter"/>
<immediateFlush>true</immediateFlush>
<rollingPolicy class="com.paytmlabs.adtech.logback.policy.S3FixedWindowRollingPolicy">
<fileNamePattern>logs/request/adtech.dealstrigger.request.${HOSTNAME}.%i.log.gz</fileNamePattern>
<markerType>REQUEST</markerType>
<prefixIdentifier>true</prefixIdentifier>
<prefixTimestamp>true</prefixTimestamp>
<rolloverOnExit>true</rolloverOnExit>
<s3BucketName>${LOGS_S3_BUCKET_NAME}</s3BucketName>
<s3FolderName>${LOGS_S3_FOLDER_NAME}/dt=%d{yyyy-MM-dd}/hr=%d{HH}/request</s3FolderName>
<shutdownHookType>SERVLET_CONTEXT</shutdownHookType>
<transferManager>${transferManager}</transferManager>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>${LOGBACK_MAX_FILE_SIZE}</maxFileSize>
</triggeringPolicy>
<!-- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">-->
<!-- <fileNamePattern>logs/request/adtech.dealstrigger.request.${HOSTNAME}.%d{yyyy-MM-dd+HH-mm}.log.gz</fileNamePattern>-->
<!-- <maxHistory>0</maxHistory> <!– Disabling archive removal. Taken care by clean up script. –>-->
<!-- <totalSizeCap>1GB</totalSizeCap>-->
<!-- </rollingPolicy>-->
</appender>
<appender class="ch.qos.logback.core.rolling.RollingFileAppender" name="AUDIT">
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%msg%xEx{3}%n</pattern>
</encoder>
<file>logs/audit/adtech.dealstrigger.audit.${HOSTNAME}.log</file>
<filter class="com.paytmlabs.adtech.config.filter.AuditLogLevelFilter"/>
<immediateFlush>true</immediateFlush>
<rollingPolicy class="com.paytmlabs.adtech.logback.policy.S3FixedWindowRollingPolicy">
<fileNamePattern>logs/audit/adtech.dealstrigger.audit.${HOSTNAME}.%i.log.gz</fileNamePattern>
<markerType>REQUEST</markerType>
<prefixIdentifier>true</prefixIdentifier>
<prefixTimestamp>true</prefixTimestamp>
<rolloverOnExit>true</rolloverOnExit>
<s3BucketName>${LOGS_S3_BUCKET_NAME}</s3BucketName>
<s3FolderName>${LOGS_S3_FOLDER_NAME}/dt=%d{yyyy-MM-dd}/hr=%d{HH}/audit</s3FolderName>
<shutdownHookType>SERVLET_CONTEXT</shutdownHookType>
<transferManager>${transferManager}</transferManager>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>${LOGBACK_MAX_FILE_SIZE}</maxFileSize>
</triggeringPolicy>
<!-- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">-->
<!-- <fileNamePattern>logs/audit/adtech.dealstrigger.audit.${HOSTNAME}.%d{yyyy-MM-dd+HH-mm}.log.gz</fileNamePattern>-->
<!-- <maxHistory>0</maxHistory> <!– Disabling archive removal. Taken care by clean up script. –>-->
<!-- <totalSizeCap>1GB</totalSizeCap>-->
<!-- </rollingPolicy>-->
</appender>
<appender class="ch.qos.logback.classic.AsyncAppender" name="ASYNC_REQUEST">
<appender-ref ref="REQUEST"/>
</appender>
<appender class="ch.qos.logback.classic.AsyncAppender" name="ASYNC_AUDIT">
<appender-ref ref="AUDIT"/>
</appender>
<logger additivity="false" level="${APP_LOGGING_LEVEL}" marker="REQUEST" name="com.paytmlabs">
<appender-ref ref="ASYNC_REQUEST"/>
</logger>
<logger additivity="false" level="${APP_LOGGING_LEVEL}" marker="AUDIT" name="com.paytmlabs">
<appender-ref ref="ASYNC_AUDIT"/>
</logger>
<logger additivity="false" level="${APP_LOGGING_LEVEL}" name="com.paytmlabs">
<appender-ref ref="ASYNC_CONSOLE"/>
</logger>
<logger additivity="false" level="${APP_LOGGING_LEVEL}" name="org.springframework">
<appender-ref ref="ASYNC_CONSOLE"/>
</logger>
<logger additivity="false" level="${APP_LOGGING_LEVEL}" name="com.amazonaws">
<appender-ref ref="ASYNC_CONSOLE"/>
</logger>
<property name="LOG_DIR" value="logs"/>
<root level="${APP_LOGGING_LEVEL}">
<appender-ref ref="ASYNC_CONSOLE"/>
<!-- <appender-ref ref="ASYNC_REQUEST"/>-->
<!-- <appender-ref ref="ASYNC_AUDIT"/>-->
</root>
</configuration>
我有一个名为
MetricsService
的服务类,它负责将指标发送到 prometheus。我想将该依赖项注入到我的 S3FixedWindowRollingPolicy
类中。
我已尝试以下方法,但不起作用:
<metricsService>${metricsService}</metricsService>
属性中使用rollingPolicy
。S3FixedWindowRollingPolicy
类中。第二种方法很可能行不通,因为 logback 和 spring 是两种不同的初始化方案。他们谁也不知道对方。所以 spring 初始化发生在它自己的上下文中,而 logback 初始化发生在它自己的上下文中。由于
S3FixedWindowRollingPolicy
类是通过 logback 初始化的,因此它将无法访问 spring 初始化的 beans。
如何将外部类依赖项注入到 S3FixedWindowRollingPolicy 类中。
不是很好(不确定是否有)解决方案,但它有效。 如果您将其作为静态变量注入,则可以访问您的
MetricsService
。
请参阅以下示例以供参考。请注意
ComponentNotManagedBySpring
是如何在 spring 上下文之外手动创建的,但仍然能够通过 SpringBean
访问
SpringBeanProvider
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
var componentNotManagedBySpring = new ComponentNotManagedBySpring();
componentNotManagedBySpring.print();
}
@Component
public static class SpringBeanProvider {
private static SpringBean staticSpringBean;
@Autowired
public void setSpringBean(SpringBean springBean) {
if(staticSpringBean != null) return;
staticSpringBean = springBean;
}
public static SpringBean getSpringBean() {
return staticSpringBean;
}
}
@Component
public static class SpringBean {
public void print() {
System.out.println("Hello Spring Bean");
}
}
//not a spring component
public static class ComponentNotManagedBySpring {
public void print() {
System.out.println("Hello NotManagedBySpring");
SpringBeanProvider.getSpringBean().print();
}
}
}