log4j2,yml - ThreadContext value is empty - log4j2

I am using spring-boot-starter-log4j2:2.1.2.RELEASE with log4j2.yml file.
on my application code,
private static final Logger logger = LogManager.getLogger(LoggingAspect.class);
...
ThreadContext.put("hostname", InetAddress.getLocalHost().getHostName());
...
logger.error("message");
and log4j2.yml file,
Appenders:
RollingRandomAccessFile:
- name: Alerts
filename: ...
filePattern: ...
PatternLayout:
Pattern: "%d{yyyy-MM-dd HH:mm:ss} %-5p %X{hostname}:%m%n"
on log file, hostname is missing while timestamp and message is showing as expected.
I've tried ${ctx:hostname}, $${ctx:hostname} but so far nothing is working for me.
Please, guide me.
Thanks!

%X{hostname} would only work if you added a hostname value to the ThreadContext. But you don’t need to do that. Log4J automatically populates a hostname variable for you. So just specify ${hostName} in your pattern.

Related

Log4j: Log only message string without logging className and other details

I have a java application and I am using log4j2.
I want to only log the log message without logging things like className, log level, timestamp etc.
I do see some suggestions regarding custom appender etc. But isn't there a simpler way to achieve this by just modifying the default configuration ?
Example:
log.info(" Hi This is a log message");
Desired Log statement
Hi This is a log message
You have to change config file log4j.xml
The element need to be change in that file is pattern :
if you are using log4j.properties then change corresponding element.
example of pattern element:
<PatternLayout pattern="%d [%p] %c %m%n"/>
here d id for date
p is for priority
c is for Class Name
m is fro message
n is fro separator
if you dont want any thing then remove from pattern entry.
Modified as per your requirement
<PatternLayout pattern=" %m%n"/>

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.

Is there a full list of uwsgi's mythical magic variables?

I'm trying to do some quite complicated configuration with uwsgi. I'm trying to make things easier on myself in the long run and naturally, in doing so, I'm making things as hard as could possibly be right now.
Anyway, I'm looking for the complete list of magic variables. The ones I've been able to find on the Emperor page are not what I'm after. The page (and others) suggests there's a larger dictionary of magic out there. Somewhere.
%v = the vassals dir
%o = the original config filename as specified in the command line
%p = the absolute path of the config filename
%s = the filename of the config file
%d = the absolute path of the directory containing the config file
%e = the extension of the config file
%n = the filename without extension
The uwsgi docs seem to have been updated since the time this question was asked. Here is a link to a longer list of magic variables:
http://uwsgi-docs.readthedocs.org/en/latest/Configuration.html#magicvars
the only missing variable is %c that reports he name of the directory containing the config file:
/foo/bar/test/one.ini will return 'test'

Ho to use xml or html layout with the Grails Log4j DSL

I am traying to get log4j to log to file in XMLLayout using the groovy log4j dsl. However, it seems that the "layout:"-part is being ignored. This is my setup:
appenders {
file name: 'fileAppender', layout: xml, file: '/tmp/logs/applog.xml', threshold: org.apache.log4j.Level.INFO
console name: "stdout", threshold: org.apache.log4j.Level.INFO
}
root {
debug 'stdout', 'fileAppender'
}
So to stdout I corectly get my info-level pattern layout, but in the file I also get pattern-layout...
What's the trick here?
This is a bug. I've fixed it for 2.0.1: http://jira.grails.org/browse/GRAILS-8635
The workaround as you found is to use the constructor explicitly instead of the DSL shortcut.
Well I found out that you can just use
layout: new XMLLayout()
or
layout: new HTMLLayout()
But still, in the documentation it says
By default the Log4j DSL assumes that you want to use a PatternLayout.
However, there are other layouts available including:
xml - Create an XML log file
html - Creates an HTML log file
simple - A simple textual log
pattern - A Pattern layout
It seems to me that the shortcuts for xml and html don't work.

Grails External Config Read Incorrectly on First Load

Grails 1.3.7
I have some configuration located in an external config file. One of the entires looks like this:
site.maintenance.mode = false
I have a filter which checks for certain config settings for specific URLs. When I do a run-app or deploy a WAR into Tomcat and do:
boolean maintenanceMode = grailsApplication.config.site.maintenance.mode
maintenanceMode is coming back true. If I look at the config object in debug mode, this is what I get:
site={maintenance={mode=false, message="<p>Our trail guides are working hard to get the system back on track.</p><p>We're sorry, the account system is down for maintenance at the moment. We'll get it back online as quickly as we can. Thanks for your patience.</p>"}}
I have a controller that I use to reload this config file dynamically and hitting this controller will fix the issue. But I'm curious as to why it is incorrect on first runs and why the discrepency in what is getting put in the maintenanceMode variable vs what is actually in the config object.
Are you using a Java properties file or a Groovy file? If you're using a properties file then I believe Grails will interpret site.maintenance.mode=false the same way as site.maintenance.mode='false' and since Groovy will interpret:
"false".asBoolean() == true
then that would explain why you would see that initial true value.
I just ran a simple test locally to verify this behavior. When I externalize my properties in a file called test.properties then site.maintenance.mode=false initially gets a boolean value of true, when I use a file called test.groovy then it interprets the boolean value of site.maintenance.mode=false as false. I believe this is because when you use a Groovy file Grails uses ConfigurationSlurper to process it but when you use a properties file Grails interprets everything as String name/value pairs.
What I do is to have an external Config.groovy file, for instance: MyConfig.groovy
At the end of the standard grails Config.groovy file, I have the following:
def ENV_NAME = "MY_EXTERNAL_CONFIG"
if(!grails.config.locations || !(grails.config.locations instanceof List)) {
grails.config.locations = []
}
if(System.getenv(ENV_NAME)) {
grails.config.locations << "file:" + System.getenv(ENV_NAME)
} else if(System.getProperty(ENV_NAME)) {
grails.config.locations << "file:" + System.getProperty(ENV_NAME)
} else {
println "No external Configs found."
}
So now you can have a MyConfig.groovy file anywhere in production environment (for example) and then set an Environment system variable to point to this file (or pass it as parameter to startup.sh), before you start tomcat:
MY_EXTERNAL_CONFIG="/home/tomcat/configs/MyConfig.groovy"
export MY_EXTERNAL_CONFIG
That's it. Now you have an external MyConfig.groovy file. The properties in it are accessible from your grails app as they were part of the standard Config.groovy
import org.codehaus.groovy.grails.commons.*
//...
ConfigurationHolder.config.foo.bar.hello

Resources