001/* 002 * Copyright 2017 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.runtime.log; 017 018import java.io.IOException; 019 020import org.apache.avalon.framework.configuration.Configurable; 021import org.apache.avalon.framework.configuration.Configuration; 022import org.apache.avalon.framework.configuration.ConfigurationException; 023import org.apache.commons.lang3.StringUtils; 024import org.apache.log4j.Appender; 025import org.apache.log4j.FileAppender; 026import org.apache.log4j.Level; 027import org.apache.log4j.LogManager; 028import org.apache.log4j.Logger; 029import org.apache.log4j.PatternLayout; 030import org.apache.log4j.rolling.RollingFileAppender; 031import org.apache.log4j.rolling.TimeBasedRollingPolicy; 032 033import org.ametys.core.util.AmetysExceptionFilter; 034import org.ametys.runtime.plugin.component.PluginAware; 035import org.ametys.runtime.util.AmetysHomeHelper; 036 037/** 038 * Default static implementation of {@link ExternalLog} 039 * For implementing the {@link ExternalLog} interface (while being {@link Configurable}), extends this class and implements the {@link #getAppender()} and/or {@link #getCategory()} methods. 040 * 041 * Example of XML 042 * <pre> 043 * {@code 044 * <extension id="runtime.core.externalLogger.myTest" 045 * class="org.ametys.runtime.log.StaticExternalLog" 046 * point="org.ametys.runtime.log.ExternalLogExtensionPoint"> 047 * <appender-name>my-logger</appender-name> 048 * <category-name>com.example.mylog</category-name> 049 * <file-prefix>my-file-name</file-prefix> 050 * <additive>false</additive> 051 * <rolling-file>true</rolling-file> 052 * <log-level>INFO</log-level> 053 * </extension> 054 * } 055 * </pre> 056 */ 057public class StaticExternalLog implements ExternalLog, Configurable, PluginAware 058{ 059 /** default layout pattern */ 060 protected static final String PATTERN_LAYOUT = "%d %-5p [%c] (%t;%X{requestURI}) %m%n"; 061 062 /** Default log level */ 063 protected static final Level DEFAULT_LEVEL = Level.WARN; 064 private String _appenderName; 065 private String _categoryName; 066 private String _filePrefix; 067 private boolean _additive; 068 private Level _level; 069 private boolean _rollingFileAppender; 070 private Appender _appender; 071 072 public Appender getAppender() throws IOException 073 { 074 if (_appender == null) 075 { 076 if (_rollingFileAppender) 077 { 078 _appender = _createRollingFileAppender(); 079 } 080 else 081 { 082 _appender = _createFileAppender(); 083 } 084 } 085 return _appender; 086 } 087 088 private RollingFileAppender _createRollingFileAppender() 089 { 090 RollingFileAppender fileAppender = new RollingFileAppender(); 091 fileAppender.setName(_appenderName); 092 TimeBasedRollingPolicy rollingPolicy = new TimeBasedRollingPolicy(); 093 String filePattern = AmetysHomeHelper.getAmetysHome() + "/logs/" + _filePrefix + "-%d.log"; 094 rollingPolicy.setFileNamePattern(filePattern); 095 fileAppender.setRollingPolicy(rollingPolicy); 096 097 PatternLayout layout = new PatternLayout(PATTERN_LAYOUT); 098 fileAppender.setLayout(layout); 099 100 AmetysExceptionFilter filter = new AmetysExceptionFilter(); 101 fileAppender.addFilter(filter); 102 fileAppender.activateOptions(); 103 return fileAppender; 104 } 105 106 private FileAppender _createFileAppender() throws IOException 107 { 108 String filename = AmetysHomeHelper.getAmetysHome() + "/logs/" + _filePrefix + ".log"; 109 PatternLayout layout = new PatternLayout(PATTERN_LAYOUT); 110 FileAppender fileAppender = new FileAppender(layout, filename); 111 AmetysExceptionFilter filter = new AmetysExceptionFilter(); 112 fileAppender.addFilter(filter); 113 fileAppender.activateOptions(); 114 return fileAppender; 115 } 116 117 public Logger getCategory() 118 { 119 org.apache.log4j.Logger logger = LogManager.getLogger(_categoryName); 120 logger.setAdditivity(_additive); 121 logger.setLevel(_level); 122 return logger; 123 } 124 125 public void configure(Configuration configuration) throws ConfigurationException 126 { 127 _categoryName = configuration.getChild("category-name").getValue("").trim(); 128 _filePrefix = configuration.getChild("file-prefix").getValue("").trim(); 129 _additive = configuration.getChild("additive").getValueAsBoolean(true); 130 _rollingFileAppender = configuration.getChild("rolling-file").getValueAsBoolean(true); 131 String levelAsString = configuration.getChild("log-level").getValue(DEFAULT_LEVEL.toString()); 132 _level = Level.toLevel(levelAsString); 133 134 if (StringUtils.isBlank(_filePrefix)) 135 { 136 throw new ConfigurationException("<file-prefix> is mandatory and should not be blank", configuration); 137 } 138 if (StringUtils.isBlank(_categoryName)) 139 { 140 throw new ConfigurationException("<category-name> is mandatory and should not be blank", configuration); 141 } 142 } 143 144 public void setPluginInfo(String pluginName, String featureName, String id) 145 { 146 _appenderName = id; 147 } 148 149}