Access maxfile size of the RollingFileAppender log4J2 programmatically - log4j2

I have a configured a RollingFileAppender using Log4J2 with the below configuration in the log4J2.properties
appender.rolling.type=RollingFile
appender.rolling.name=logFile
appender.rolling.fileName=${sys\:catalina.home}/logs/server.log
appender.rolling.filePattern=${sys\:catalina.home}/logs/app_%d{yyyyMMdd}.log.gz
appender.rolling.layout.type=PatternLayout
appender.rolling.layout.pattern=%d %p [%t %c] - %m%n
appender.rolling.policies.type=Policies
appender.rolling.policies.size.type=SizeBasedTriggeringPolicy
appender.rolling.policies.size.size=10240KB
rootLogger.level=INFO
rootLogger.appenderRef.rolling.ref=logFile
I would like to access the value of appender.rolling.policies.size.size programmatically at runtime
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
RollingFileAppender rapp = config.getAppender("logFile");
But I don't see any methods available to access the current maximum size of the log file. Is there any alternative approach to get the data?

Related

How to pass value in log4j2 JSON layout configuration the value of KeyValuePair from code?

I want to pass some value from my code to my logs which in JSON format. The key of that value should define in log configuration file.
My XML configuration log4j2-spring.xml is as follow:
<Console name="Console" target="SYSTEM_OUT">
<JsonLayout complete="false" stacktraceAsString="true" eventEOL="true" compact="true">
<KeyValuePair key="ValueFromCode" value="Value"/>
</JsonLayout>
</Console>
When I write
Logger logger = LogManager.getLogger(this.getClass());
logger.info("TestXXX")
the above configuration writes log as
{"instant":{"epochSecond":1625138085,"nanoOfSecond":35827700},"thread":"XXXXX","level":"INFO","loggerName":"XXXXXXX","message":"TestXXX","endOfBatch":false,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","threadId":XX,"threadPriority":X,"ValueFromCode":"Value"}
I want to pass the value of this Key ValueFromCode from my code. Something like,
Logger logger = LogManager.getLogger(this.getClass());
logger.info("TestXXX","some value for Key ValueFromCode")
and this should write my log as
{"instant":{"epochSecond":1625138085,"nanoOfSecond":35827700},"thread":"XXXXX","level":"INFO","loggerName":"XXXXXXXXXX","message":"TestXXX","endOfBatch":false,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","threadId":XX,"threadPriority":X,"ValueFromCode":"some value for Key ValueFromCode"}
Please tell me if this is achievable. If there is any alternate way to achieve the same.

Log4J2 - changing the fileName at runtime

Can anybody let me know if it is possible to change the fileName at runtime.
I have migrated my log4j.properties to log4j2.properties successfully so far. The appenders, loggers are all being created. If I hard code the fileName then my logs are getting populated. But unfortunately the logname has to be the service name and I will know the service name only at runtime.This was possible earlier with Log4j 1.x. Earlier Call to fileAppender.setFile(logFile.getAbsolutePath()); would change the fileName during runtime. I now need to do something similar with log4J 2.4.1. I tried removing the appender,recreating it programmatically and adding the appender to the configuration but no success. Empty logfiles are being created but with the correct name. Please can anybody help me as I am just not able to figure this out. Below is my code snippet where I am trying to delete,recreate the appender.
RollingFileAppender fileAppender = (RollingFileAppender) this.config.getAppender(loggerName);
String filePattern = fileAppender.getFilePattern();
TriggeringPolicy policy = fileAppender.getTriggeringPolicy();
RolloverStrategy strategy = fileAppender.getManager().getRolloverStrategy();
PatternLayout layout = (PatternLayout) fileAppender.getLayout();
Filter filter = fileAppender.getFilter();
LoggerConfig lgConfig = this.config.getLogger(loggerName);
RollingFileAppender rollingFile = RollingFileAppender.createAppender(fileName, filePattern, "true", loggerName, (String)null, (String)null, (String)null, policy, strategy, layout, filter, (String)null, "false", (String)null, config);
config.removeAppender(loggerName);
config.removeLogger(loggerName);
config.addLogger(loggerName, lgConfig);
context.updateLoggers();
config.addAppender((Appender)rollingFile);
logger = LogManager.getLogger(loggerName);
"fileName" is already set by the time we reach this bit of code.
You should be able to create a custom Lookup to get your service name and then reference that in the configuration file.
Here is an example of how to create a custom Lookup.

Jasypt: read configuration from external file

I am using grails Jasypt Encryption plugin to encrypt my data in the DB.
If I set jasypt configurations in my Config.groovy file like:
jasypt {
algorithm = "PBEWITHSHA256AND256BITAES-CBC-BC"
providerName = "BC"
password = "myPassphrase"
keyObtentionIterations = 1000
}
then everything is working fine.
But if I move the jasypt configurations in an external file as mentioned in the jasypt doc(External Config Files in Grails) then these configuration are not being accessed.
How to access jsypt external configuration file?
Note:- Using ubuntu
Since your Jasypt config block uses ConfigSlurper syntax, your external config file needs a .groovy extension (e.g. .jasypt.groovy) Or, you could switch to Java .properties syntax.
If you just copy-pasted this section:
def configFIlePath = System.getenv('ENCRYPTION_CONFIG_LOCATION') ?: "file:${userHome}/.jasypt"
grails.config.locations = [configFilePath]
pay special attention to the typo: in the first line it must be configFilePath with a lower-case i!!

log4j : parameter appender file name

I use Grails
In my file Config.groovy I create an appender as:
log4j = {
appenders {
file name:'myAppli', file:'/tmp/myAppli.log'
}
...
}
Is it possible to parameter file path of my appender through data of file.properties ?
something like that :
file.properties:
myAppli.log.path=C:\\tmp\\
Config.groovy:
appenders {
file name:'myLogs', file:myAppli.log.path + 'myLogs.log'
}
myAppli.log.path should work!!!
There's a section in the docs for this: externalized configuration. You can set a absolute location or let Grails look into the classpath. Here's the example of the docs:
grails.config.locations = [
"classpath:${appName}-config.properties",
"classpath:${appName}-config.groovy",
"file:${userHome}/.grails/${appName}-config.properties",
"file:${userHome}/.grails/${appName}-config.groovy" ]
EDIT: I tested here. It appears that the value is only available throught the config object during runtime and not available inside Config.groovy. According to this thread it's not possible to do what you want.
You're almost right. The log4j closure is executed after the whole configuration has been parsed and assembled, and within the closure you have access to the complete configuration via the variable config. You can say
grails.config.locations = ['file:file.properties']
log4j = {
appenders {
file name:'myAppli', file:"${config.myAppli.log.path}myLogs.log"
}
// ...
}
I've tested this with Grails 2.2: run grails create-app log4jtest to create a new application, then edit log4jtest/grails-app/conf/Config.groovy to add at the top
grails.config.locations = ["file:file.properties"]
logfile.name = "from-config.log"
and for the log4j closure
// log4j configuration
log4j = {
println "filename: ${config.logfile.name}"
// rest of closure as before
Run this app using grails run-app and you'll see it print filename: from-config.log (twice, in fact). Now create a file named file.properties in the top-level log4jtest folder containing the line
logfile.name=from-external.log
Run the app again and this time it will print filename: from-external.log instead.

hiding database password using codec specification in datasource.groovy not working

I am hiding the database password in datasource.groovy by doing
dataSource {
pooled = true
driverClassName = "com.mysql.jdbc.Driver"
username = "root"
password = "q59YgJCdHw3dshwlsa=="
passwordEncryptionCodec = DESCodec
dbname="mydbname"
}
followed the artilce : http://jira.grails.org/browse/GRAILS-3620
I run the groovy codec class separately to get the encrypted string like this:
groovy grails-app/utils/DESCodec.groovy mypassword_string_text.
But After placing the DESCodec class in the Utility package in grails, when I try to start the server, it wont start but directly shutdown, It starts when I directly put the right password and comment out the codec and encrypted string. I am assuming it is not finding the codec class/anything else I am missing in the config like specifying the codec class requires quotes or any path change or I should change the algorithm, by the way the DESCodec class is the last codec class in the link.
I am working on getting the config to be environment specific and externalized, but I still need the password to be encrypted here, and then decrypted before connecting to the database.
I think the best way to do this is to externalise environment specific configuration (especially passwords, but URL's, email addresses and so on too) and then protect the config file with proper permissions on the file system of the target machine.
In Config.groovy (for example):
grails.config.locations = [
"file:/etc/${appName}/conf/db.properties"
]
and in the config file:
dataSource.username = "root"
dataSource.password = "secret"
I typically do this for production config, but keep dev/test config in the Config.groovy for convenience. When running in dev/test you simply get a warning at startup if it can't find the referenced config file. If it does find it, then it will override what's in Config.groovy
This has the added advantage of not requiring your war file to be recompiled and redeployed if any prod environment configuration changes, you simply change the config file and restart the app.

Resources