I need to create a rollingfile appender and set the amount of logfiles during runtime with log4j2. So I use the following code to achive that:
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
DefaultRolloverStrategy strategy = DefaultRolloverStrategy.newBuilder()
.withMax("4")
.withMin("1")
.withFileIndex("max")
.withConfig(config)
.withCompressionLevelStr(Deflater.NO_COMPRESSION + "")
.build();
PatternLayout layout = PatternLayout.newBuilder().withConfiguration(config)
.withPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} [%5p] %pid --- %-40.40logger{39} : %m%n%wEx")
.build();
RollingFileAppender appender = RollingFileAppender.newBuilder().setConfiguration(config)
.withName("TraceFileAppender")
.withLayout(layout)
.withFileName("log.log")
.withFilePattern("log.%d{yyyy-MM-ddHHmmSSS}.log")
.withPolicy(SizeBasedTriggeringPolicy.createPolicy("20KB")
.withStrategy(strategy)
.build();
appender.start();
config.addAppender(appender);
LoggerConfig loggerConfig = config.getRootLogger();
loggerConfig.setLevel(Level.toLevel("DEBUG"));
loggerConfig.addAppender(appender, null, null);
This is working fine except from the max amount of files... I`m getting more files than the 4 in my strategy.... what is wrong? Any help is welcome!
Thanks in advance,
Regards Peter
pfff took me a while but I got it working... Not a lot information about programmaticaly changing log4j2 appenders here so this is my solution:
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
PathCondition[] pathConditions = new PathCondition[1];
pathConditions[0] = IfAccumulatedFileCount.createFileCountCondition(Integer.parseInt(expire));
DeleteAction action = DeleteAction.createDeleteAction("C:\\logs\\BuddyServer\\", true, 1, false, null, pathConditions, null, config);
Action[] actions = new Action[1];
actions[0] = action;
DefaultRolloverStrategy strategy = DefaultRolloverStrategy.newBuilder()
.withMax(expire)
.withCustomActions(actions)
.withMin("1")
.withFileIndex("max")
.withConfig(config)
.withCompressionLevelStr(Deflater.NO_COMPRESSION + "")
.build();
PatternLayout layout = PatternLayout.newBuilder().withConfiguration(config)
.withPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} [%5p] %pid --- %-40.40logger{39} : %m%n%wEx")
.build();
RollingFileAppender appender = RollingFileAppender.newBuilder().setConfiguration(config)
.withName("TraceFileAppender")
.withLayout(layout)
.withFileName(file + ".log")
.withFilePattern(file + ".%d{yyyy-MM-ddHHmmSSS}.log")
.withPolicy(SizeBasedTriggeringPolicy.createPolicy(segment))
.withStrategy(strategy)
.build();
appender.start();
config.addAppender(appender);
LoggerConfig loggerConfig = config.getRootLogger();
loggerConfig.setLevel(Level.toLevel(buddyConfig.getOption("log", "verbose").toUpperCase()));
loggerConfig.addAppender(appender, null, null);
Related
Help
Why can't I get serilog to log to sqlserver
I have used forever to get this to work
It logs fine to the console
I have installed the nuget packages
Serilog
Serilog.Sinks.Console
Serilog.Sinks.MSSqlServer
//First a quick test if the connection string works (db can open, and if the table exists, it works but no rows
var connection = new ConnectionStringSettings();
connection.ConnectionString = "Data Source=server-name;Initial Catalog=db-name;Persist Security Info=True;User ID=user-name;Password='password-name'";
var sqlc = new SqlConnection(connection.ConnectionString);
string query = "select * from LogEvents";
sqlc.Open();
using (var command = new SqlCommand(query, sqlc))
{
var reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
}
}
reader.Close();
}
sqlc.Close();
var log = new LoggerConfiguration()
.WriteTo
.MSSqlServer(
connectionString: connection.ConnectionString,
sinkOptions: new MSSqlServerSinkOptions { TableName = "LogEvents", AutoCreateSqlTable = true }
)
.WriteTo.Console()
.CreateLogger();
Log.Logger = log;
Log.Information("123");
Log.CloseAndFlush();
Console.WriteLine("Hello, World!");
Below are the programmatic configurations of consoleAppender and LogAppenders which I have converted for log4j upgrade from 1.. to 2.17.1 version.
//Programmatic configuration of ConsoleAppender log4j2
String pattern = "%d{DATE} [%p|%C{2}] %m%n";
ConfigurationBuilder<BuiltConfiguration> builder =
ConfigurationBuilderFactory.newConfigurationBuilder();
builder.setConfigurationName("DefaultLogger");
// Create pattern layout
LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout")
.addAttribute("pattern", pattern);
AppenderComponentBuilder appenderBuilder = builder.newAppender("Console", "CONSOLE")
.addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
appenderBuilder.add(layoutBuilder);
builder.add(appenderBuilder);
RootLoggerComponentBuilder rootLogger
= builder.newRootLogger(Level.DEBUG);
rootLogger.add(builder.newAppenderRef("Console"));
builder.add(rootLogger);
Configurator.initialize(builder.build());
Configurator.reconfigure(builder.build());
//RollingFileAppender Programmatic configuration log4j2:
CdasLogger() {
// CreateLogger takes a path for each logger from config file
loadLog = createLogger("load.log");
updateLog = createLogger("update.log");
userLog = createLogger("user.log");
}
private Logger createLogger(String logType) {
String pattern = "%d %M - %m%n";
String consolePattern = "%d{DATE} [%p|%C{2}] %m%n";
String fileLogName = "/app/app.log";
String filePattern = "/app/app.log-%d{MM-dd-yy}.log.gz";
System.out.println("logtype is::" + logType);
String path = ConfigReader.getStringValue(logType);
System.out.println(path);
String daily = "0 0 12 1/1 * ? *";
// Initializing the logger context
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
ConfigurationBuilder<BuiltConfiguration> builder =
ConfigurationBuilderFactory.newConfigurationBuilder();
builder.setConfigurationName("rollingFileLogger");
//specifying the pattern layout
LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout")
.addAttribute("pattern", pattern);
//specifying the policy for rolling file
ComponentBuilder triggeringPolicy = builder.newComponent("Policies")
. addComponent(builder.newComponent("SizeBasedTriggeringPolicy").addAttribute("size", "10MB"));
//create a rollingfile appender
AppenderComponentBuilder appenderBuilder = builder.newAppender("rollingFile", "RollingFile")
.addAttribute("fileName", path)
.addAttribute("filePattern", path+"-%d{MM-dd-yy-HH-mm-ss}.log.")
.add(layoutBuilder)
.addComponent(triggeringPolicy);
builder.add(appenderBuilder);
RootLoggerComponentBuilder rootLogger = builder.newRootLogger(Level.TRACE);
rootLogger.add(builder.newAppenderRef("rollingFile"));
builder.add(rootLogger);
ctx = Configurator.initialize(builder.build());
Configurator.reconfigure(builder.build());
return ctx.getLogger(logType); // return the logger to the caller
}
Console Appender gets initialized first and the logs are written. After Initializing the rollingfileappender. All the logs are getting written to rollingfile Appender. There are no logs to consoleAppender once the rollingfile appender is initalized.
EDIT 1:
As per Piotr comments, I made the below change to have same configuration builder for all the appenders.
private void configureLogger() {
ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
// create a console appender
AppenderComponentBuilder console
= builder.newAppender("stdout", "Console").addAttribute("target",
ConsoleAppender.Target.SYSTEM_OUT);
console.add(builder.newLayout("PatternLayout").addAttribute("pattern",
"%d{DATE} [%p|%C{2}] %m%n"));
RootLoggerComponentBuilder rootLogger
= builder.newRootLogger(Level.DEBUG);
rootLogger.add(builder.newAppenderRef("stdout"));
builder.add(console);
// create a rolling file appender
String pattern = "%d %M - %m%n";
//specifying the pattern layout
LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout")
.addAttribute("pattern", pattern);
//specifying the policy for rolling file
ComponentBuilder triggeringPolicy = builder.newComponent("Policies")
.addComponent(builder.newComponent("SizeBasedTriggeringPolicy").addAttribute("size", "10MB"));
String[] logTypes = {"load.log", "update.log", "user.log"};
for (String logType : logTypes) {
System.out.println("logtype is::" + logType);
String path = ConfigReader.getStringValue(logType);
System.out.println(path);
AppenderComponentBuilder appenderBuilder = builder.newAppender(logType, "RollingFile")
.addAttribute("fileName", path == null ? "/app1/app.log" : path)
.addAttribute("filePattern", path == null ? "/app1/app.log" : path+"-%d{MM-dd-yy-HH-mm-ss}.log.")
.add(layoutBuilder)
.addComponent(triggeringPolicy);
builder.add(appenderBuilder);
rootLogger.add(builder.newAppenderRef(logType));
}
builder.add(rootLogger);
Configurator.reconfigure(builder.build());
}
The logs are not updating still.
calling configureLogger() method during app start up.
In another class I have the code below
public class CdasLogger {
private final Logger updateLog, loadLog, userLog;
CdasLogger() {
loadLog = createLogger("load.log");
updateLog = createLogger("update.log");
userLog = createLogger("user.log");
}
private Logger createLogger(String logType) {
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
return ctx.getLogger(logType);
}
}
I'm having issues with WriteTo.MSSqlServer not wring to the configured database. AutitTo.MSSqlServer work fine. This is in a console app, C#. Not Core.
I've looked all over and everything I've found is a dead end. Getting a little frustrated
Code:
var sinkOptions = new SinkOptions() {
TableName = "Logs",
AutoCreateSqlTable = true,
SchemaName = "dbo"
};
//Create/Configure the logger
_logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File(#"C:\Users\c.clover\source\repos\ConsoleApp3\ConsoleApp3\Log.txt")
.WriteTo.MSSqlServer(
"Server=TEST01;Database=LogDb;Trusted_Connection=True;",
sinkOptions,
null,
null,
Serilog.Events.LogEventLevel.Information
)
.AuditTo.MSSqlServer(
"Server=TEST01;Database=LogDb;Trusted_Connection=True;",
sinkOptions,
null,
null,
Serilog.Events.LogEventLevel.Information
)
.CreateLogger();
//Log something
_logger.Information("Test Log {Now}", DateTime.Now);
Log.CloseAndFlush();
}
}
I fixed the problem by bagging ILogger _logger and using Log instead
Log.Logger = new LoggerConfiguration()... etc
Log.Information.... etc.
Log.CloseAndFlush();
What I dont get is why it doesnt work with ILogger?
I use shiro-vaadin-integration plugin
#WebServlet(urlPatterns = "/*", name = "Test", asyncSupported = true,
initParams = #WebInitParam(name = Constants.I18N_PROVIDER,
value = "com.test.TranslationProvider"))
#VaadinServletConfiguration(productionMode = false)
#Slf4j
public class AppServlet extends VaadinServlet {
#Override
protected void servletInitialized() throws ServletException {
log.info("Init Shiro");
IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
DefaultSecurityManager securityManager = new DefaultSecurityManager(iniRealm);
// SessionDAO sessionDAO = new MemorySessionDAO();
// ((DefaultSessionManager) securityManager.getSessionManager()).setSessionDAO(sessionDAO);
// securityManager.setCacheManager(new MemoryConstrainedCacheManager());
SecurityUtils.setSecurityManager(securityManager);
log.info("Finish Init Shiro");
super.servletInitialized();
}
The crux of the problem is that after logging in. I throws on the main page.
SecurityUtils.getSubject().isAuthenticated()
Return true.
Further, when trying to navigate in the application.
SecurityUtils.getSubject().isAuthenticated()
Return false.
It feels like a session lasts a couple of seconds
shiro.ini
[main]
authc.loginUrl = /signin
vaadin = org.vaadin.shiro.VaadinNavigationRolesAuthorizationFilter
vaadin.loginUrl = /signin
[users]
admin#admin.com = 1#QWaszx, admin
user = user, user
[roles]
admin = *
user = action1:*
[urls]
/ = anon, vaadin
/signin = anon, vaadin
/signup = anon, vaadin
/forgot-password = anon, vaadin
/reset-password = anon, vaadin
/registration-complete = anon, vaadin
/create-account = anon, vaadin
/payment = anon, vaadin
/environment = authc, vaadin[admin]
/billing = authc, vaadin[admin]
/settings = authc, vaadin[admin]
If we follow the link quickly after authorization, it will pass.
And if you wait for the application falls
Here is how I configure and start my Quartz.Net scheduler in 1.x:
properties["quartz.scheduler.instanceName"] = instanceName;
properties["quartz.scheduler.instanceId"] = "AUTO";
properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
properties["quartz.threadPool.threadCount"] = threadCount;
properties["quartz.threadPool.threadPriority"] = "Normal";
properties["quartz.jobStore.misfireThreshold"] = "60000";
properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz";
properties["quartz.jobStore.useProperties"] = "true";
properties["quartz.jobStore.dataSource"] = "default";
properties["quartz.jobStore.tablePrefix"] = tablePrefix;
properties["quartz.jobStore.clustered"] = "false";
properties["quartz.jobStore.lockHandler.type"] = "Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz";
properties["quartz.dataSource.default.connectionString"] = connectionString;
properties["quartz.dataSource.default.provider"] = "SqlServer-20";
schedFact = new StdSchedulerFactory(properties);
svcScheduler = schedFact.GetScheduler();
svcScheduler.Start();
After migrating to 2.x will I have to change something here and what?
Most importantly is quartz.dataSource.default.provider for SQL Server still SqlServer-20 or did something change there?
Nothing has really changed in the configuration of Quartz.net 2.x.
You can find some useful information here.
Yes, you still have to use SqlServer-20 if you want to use MS Sql Server.
For a full list of db provider have a look here.