当前位置:网站首页>[log4j2 log framework] modify dump log file permissions

[log4j2 log framework] modify dump log file permissions

2022-06-13 07:26:00 Small side good side

0. background

For systems with strict safety requirements , Dump compressed log file , File permissions are required to be read-only , And I've looked all over log4j2 Information , No such configuration has been found ,log4j2 The default permissions of the framework for logs are 640, Keep writeable permissions for log files anyway , It seems that permissions cannot be configured for compressed logs alone . however log4j2 It supports custom log scrolling policies , Simply study how to extend... Directly from the source code log4j2 Log plugin .

1. Analyze the solution ideas

Generally, we choose rolling.strategy.type When I choose DefaultRolloverStrategy, The implementation of the whole rolling strategy is still very complicated , I just want to implement this function with minimal changes .DefaultRolloverStrategy The core logic is rollover in , This method is to construct a RolloverDescription Example , Observation structure RolloverDescription Parameters required by the instance

 Insert picture description here
 Insert picture description here
The last parameter is the processing class of the compressed file , The first three parameters don't matter . When we configure the compressed log format as gz when , The implementation class of the fourth parameter is GzCompressAction, Its core approach execute It's just that you're going to .log The file is compressed to .gz file . I don't want to modify the whole log scrolling strategy , I just want to be here GzCompressAction Of execute Method is followed by a method to modify the permissions of the compressed file .

2、 Expand GzCompressAction

 Insert picture description here
GzCompressAction from final Decoration cannot inherit , The easiest way is to inherit its parent class , And will GzCompressAction As a member . Realization execute Method without relation to the original GzCompressAction Specific logic , Directly call the member's execute Method , Then call the method I provided to modify the file permissions . In this way, the original logic that I just said will not be changed , Modify file permissions only after compression .

public class CustomGzCompressAction extends AbstractAction {
    
    private final GzCompressAction gzCompressAction;

    public CustomGzCompressAction(GzCompressAction gzCompressAction) {
    
        this.gzCompressAction = gzCompressAction;
    }

    @Override
    public boolean execute() throws IOException {
    
        boolean result = gzCompressAction.execute();
        File destination = gzCompressAction.getDestination();
        if (destination != null) {
    
            FilePermissionUtil.chmodLogFile(destination);
        }
        return result;
    }
}

FilePermissionUtil

public class FilePermissionUtil {
    
    private static final Logger LOG = LoggerFactory.getLogger(FilePermissionUtil.class);

    /** *  Modify file permissions to read-only  * * @param fileName  File path  */
    public static void chmodLogFile(File fileName) {
    
        try {
    
            LOG.info("change log file permission");
            Set<PosixFilePermission> perms = EnumSet.of(OWNER_READ, GROUP_READ);
            if (Files.readAttributes(fileName.toPath(), PosixFileAttributes.class) != null) {
    
                PosixFileAttributes attr = Files.readAttributes(fileName.toPath(), PosixFileAttributes.class);
                attr.permissions().clear();
            }
            Files.setPosixFilePermissions(fileName.toPath(), perms);
        } catch (FileNotFoundException e) {
    
            LOG.error("file nod found ,fileName={}", fileName);
        } catch (IOException e) {
    
            LOG.error("change file permission error", e);
        }
    }
}

3、 Expand DefaultRolloverStrategy

because log4j2 It loads the scrolling strategy in the form of a plug-in , So we want to be like DefaultRolloverStrategy Define the custom scrolling policy as a plug-in . It's going to be DefaultRolloverStrategy Copy the code of , utilize DefaultRolloverStrategy Instance construction of CustomRolloverStrategy.

@Plugin(name = "CustomRolloverStrategy", category = Core.CATEGORY_NAME, printObject = true)
public class CustomRolloverStrategy extends DefaultRolloverStrategy {
    
    private static final Logger LOG = LoggerFactory.getLogger(CustomRolloverStrategy.class);

    protected CustomRolloverStrategy(int minIndex, int maxIndex,
                                    boolean useMax, int compressionLevel,
                                    StrSubstitutor strSubstitutor, Action[] customActions,
                                    boolean stopCustomActionsOnError,
                                    String tempCompressedFilePatternString) {
    
        super(minIndex, maxIndex, useMax,
                compressionLevel, strSubstitutor,
                customActions, stopCustomActionsOnError,
                tempCompressedFilePatternString);
    }

    protected CustomRolloverStrategy(
            int minIndex, int maxIndex, boolean useMax,
            int compressionLevel, StrSubstitutor strSubstitutor,
            Action[] customActions, boolean stopCustomActionsOnError) {
    
        super(minIndex, maxIndex, useMax,
                compressionLevel, strSubstitutor,
                customActions, stopCustomActionsOnError);
    }

    /** * Strateg Construction factory * * @param max  Maximum number of files  * @param min  Minimum number of files  * @param fileIndex  Maximum file index  * @param compressionLevelStr  Compression level  * @param customActions  Customize Action * @param stopCustomActionsOnError  Customize Action Whether to stop when an error occurs  * @param config  Other configuration  * @return CustomRolloverStrategy */
    @PluginFactory
    public static CustomRolloverStrategy createStrategy(
            // @formatter:off
            @PluginAttribute("max") final String max,
            @PluginAttribute("min") final String min,
            @PluginAttribute("fileIndex") final String fileIndex,
            @PluginAttribute("compressionLevel") final String compressionLevelStr,
            @PluginElement("Actions") final Action[] customActions,
            @PluginAttribute(value = "stopCustomActionsOnError",
                    defaultBoolean = true)
            final boolean stopCustomActionsOnError,
            @PluginConfiguration final Configuration config) {
    
        DefaultRolloverStrategy defaultRolloverStrategy = DefaultRolloverStrategy.newBuilder()
                .withMin(min)
                .withMax(max)
                .withFileIndex(fileIndex)
                .withCompressionLevelStr(compressionLevelStr)
                .withCustomActions(customActions)
                .withStopCustomActionsOnError(stopCustomActionsOnError)
                .withConfig(config)
                .build();
        CustomRolloverStrategy customRolloverStrategy
                = new CustomRolloverStrategy(defaultRolloverStrategy.getMinIndex(),
                defaultRolloverStrategy.getMaxIndex(), defaultRolloverStrategy.isUseMax(),
                defaultRolloverStrategy.getCompressionLevel(),
                defaultRolloverStrategy.getStrSubstitutor(),
                customActions, defaultRolloverStrategy.isStopCustomActionsOnError());
        return customRolloverStrategy;
    }

    /** *  Rewrite the DefaultRolloverStrategy Of rollover * * @param manager manager * @return RolloverDescription * @throws SecurityException */
    @Override
    public RolloverDescription rollover(RollingFileManager manager) throws SecurityException {
    
        RolloverDescription result = super.rollover(manager);
        Action asynchronous = result.getAsynchronous();
        if (asynchronous instanceof GzCompressAction) {
    
            asynchronous = new CustomGzCompressAction((GzCompressAction) asynchronous);
        }

        return new RolloverDescriptionImpl(result.getActiveFileName(), false, result.getSynchronous(), asynchronous);
    }

}

rollover The implementation of is also to call the parent class rollover, Then return the parent class to the asynchronous Replace with our extended CustomGzCompressAction, Other parameters unchanged .

4、 To configure

take log4j2.properties Medium rolling.strategy.type Replace all with CustomRolloverStrategy, This enables us to modify the permissions of compressed log files .
 Insert picture description here

5、 effect

The log permissions in the record are 6xx, Compressed gz by 440
 Insert picture description here

原网站

版权声明
本文为[Small side good side]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202270549071714.html