Log4j configuration in Grails production environment with grails.config.locations - grails

I am trying to maintain the log4j configuration in a separate file in production environment. I have this log4j.properties file (which in production resides in WEB-INF/classes):
log4j.rootLogger=error, stdout
log4j.rootLogger.additivity=false
log4j.logger.grails.app=info, stdout
log4j.additivity.grails.app=false
log4j.additivity.grails.app.service=false
log4j.logger.grails.app.controller=debug, stdout
log4j.additivity.grails.app.controller=false
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%7r] %6p - %14.14c - %m%n
I completely removed the log4j configuration from the Config.groovy. And according to the second option in this comment http://jira.codehaus.org/browse/GRAILS-2730?focusedCommentId=137021&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_137021 I added the location of log4j.properties in Config.groovy this way:
production {
grails.serverURL = "http://xxxxx.ru/${appName}"
grails.config.locations = [ "classpath:log4j.properties" ]
}
But when deploying the application I still get the exception about the stacktrace.log file:
log4j:ERROR setFile(null,true) call failed.
java.io.FileNotFoundException: stacktrace.log (Permission denied)
at java.io.FileOutputStream.openAppend(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:207)
at java.io.FileOutputStream.<init>(FileOutputStream.java:131)
at org.apache.log4j.FileAppender.setFile(FileAppender.java:294)
at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:165)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
...
I do not understand why.. Anyone?
Thanks.

java.io.FileNotFoundException: stacktrace.log (Permission denied)
should mean that the user that Tomcat is running under does not have proper write permissions in the folder where Log4J tries to create the stacktrace.log file. By default, this is the folder that had been the working directory when Tomcat had been started.
You can specify a custom stacktrace.log location with the log4j.appender.stacktraces.File configuration option, like so:
log4j.logger.stacktraces.com.foo=INFO,stacktraces
log4j.additivity.stacktraces=false
log4j.appender.stacktraces=org.apache.log4j.DailyRollingFileAppender
log4j.appender.stacktraces.File=${log.dir}/fooStacktraces.log
log4j.appender.stacktraces.DatePattern=${roll.pattern.daily}
log4j.appender.stacktraces.layout=org.apache.log4j.PatternLayout
log4j.appender.stacktraces.layout.ConversionPattern=%d{${datestamp}}%p%m%n

By default, properties files (like any other resources that are not compiled) are not copied to the WEB-INF/classes folder.
To copy them, manually, create the file scripts/Events.groovy in your project and add the following code (assuming that your properties file is in the application root):
eventCompileEnd = {
ant.copy(todir:classesDirPath) {
fileset(file:"${basedir}/*.properties")
}
}

Related

Can't add a rolling file appender with Log4j2.properties

I have a java application running in a docker container. I can't change the program but I can change the log4j2.properties file. I want to add a rolling file appender but when I do it I get this error:
ERROR An exception occurred processing Appender file_appender java.security.AccessControlException: access denied ("java.io.FilePermission" "shared_logs" "read")
Then I gave all permissions to my shared_logs folder
chmod 777 shared_logs
But the error is still there.
This is how I added the the appender:
appender.fa.type = RollingFile
appender.fa.name = file_appender
appender.fa.fileName = shared_logs/elastic.log
appender.fa.filePattern = shared_logs/elastic-%d{yyyy-dd-MM}-%i.log.gz
appender.fa.layout.type = PatternLayout
appender.fa.layout.pattern = [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
appender.fa.policies.type = Policies
appender.fa.policies.time.type = TimeBasedTriggeringPolicy
appender.fa.policies.size.type = SizeBasedTriggeringPolicy
appender.fa.policies.size.size = 500
appender.fa.strategy.type = DefaultRolloverStrategy
appender.fa.strategy.max = 5
"fa" stands for fileappender
Well, you obviously still have a permissions problem. Your fileName is a relative file so where it is being created will be based on the currently directory of your app. That would typically be either the directory your app is in or the root directory. If it is the root directory and you are expecting it to be in your app this would explain the problem. If you add -Dlog4j2.debug to the startup options you would see where Log4j is trying to create the file.
Writing to log files in Docker Containers is also not usually considered a best practice. If you haven't already, I would suggest taking a look at Logging in the Cloud on the Log4j web site.

SeqFilesFromDirectory() error on amazon EMR

I am trying to run a simple program on Amazon EMR which converts text files in a directory into sequence files. The program runs fine on my local machine but gives me following error on Amazon EMR. Could someone please tell me how to get rid of this error.
Configuration conf=new Configuration();
System.out.println("fs.default.name : - " + conf.get("fs.default.name"));
Path input=new Path(URI.create(args[0]));
Path output=new Path(URI.create(args[1]));
ToolRunner.run(new SequenceFilesFromDirectory(),new String[]{
"--input",input.toString(),
"--output",output.toString(),
"--overwrite",
"--method","mapreduce"});
Thank you.
Exception in thread "main" java.lang.IllegalArgumentException: This file system object (hdfs://172.31.4.175:9000) does not support access to the request path ..
You possibly called FileSystem.get(conf) when you should have called FileSystem.get(uri, conf) to obtain a file system supporting your path.
at org.apache.hadoop.fs.FileSystem.checkPath(FileSystem.java:384)
at org.apache.hadoop.hdfs.DistributedFileSystem.getPathName(DistributedFileSystem.java:129)
at org.apache.hadoop.hdfs.DistributedFileSystem.getFileStatus(DistributedFileSystem.java:513)
at org.apache.mahout.text.SequenceFilesFromDirectory.runMapReduce(SequenceFilesFromDirectory.java:140)
at org.apache.mahout.text.SequenceFilesFromDirectory.run(SequenceFilesFromDirectory.java:89)
at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:65)
at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:79)
at com.gifts.text.SeqFileDirectory.main(SeqFileDirectory.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.hadoop.util.RunJar.main(RunJar.java:187)*

Need help resolving error message

Just tried to deploy a .war file and received this error message. This came quite the surprise to me because I just deployed a .war file the day before and worked fine with minimal changes between the two (changed a value of a variable that tracks days until a cron job executes). I do leave out the auto generated .iml files that IntelliJ creates, could that do it?
'2014-01-24 08:47:45,480 [Thread-10] WARN config.ConfigurationFactory - No configuration found. Configuring ehcac he from ehcache-failsafe.xml found in the classpath: jar:file:/var/opt/tomcat/webapps/PerformanceEvaluations-moved /WEB-INF/lib/ehcache-core-2.4.6.jar!/ehcache-failsafe.xml
''2014-01-24 08:47:46,117 [Thread-10] WARN hibernate.AbstractEhcacheRegionFactory - Couldn't find a specific ehca che configuration for cache named [edu.wisc.radiology.performanceevaluations.Role]; using defaults.
' ==> PerformanceEvaluations_main.log <== '2014-01-24 08:47:45,480 [Thread-10] WARN config.ConfigurationFactory - No configuration found. Configuring ehcac he from ehcache-failsafe.xml found in the classpath: jar:file:/var/opt/tomcat/webapps/PerformanceEvaluations-moved /WEB-INF/lib/ehcache-core-2.4.6.jar!/ehcache-failsafe.xml
''2014-01-24 08:47:46,117 [Thread-10] WARN hibernate.AbstractEhcacheRegionFactory - Couldn't find a specific ehca che configuration for cache named [edu.wisc.radiology.performanceevaluations.Role]; using defaults.
' ==> catalina.out <==
'2014-01-24 08:47:49,046 [Thread-10] WARN servlet.DefaultGrailsApplicationAttributes - ApplicationContext not fou nd in org.codehaus.groovy.grails.APPLICATION_CONTEXT attribute of servlet context.
' ==> PerformanceEvaluations_main.log <==
'2014-01-24 08:47:49,046 [Thread-10] WARN servlet.DefaultGrailsApplicationAttributes - ApplicationContext not fou nd in org.codehaus.groovy.grails.APPLICATION_CONTEXT attribute of servlet context.
' ==> catalina.out <==
'2014-01-24 08:47:50,112 [Thread-10] WARN module.ModuleDeclarationsFactory - 'grails.resources.modules' in config does not define any modules
'==> PerformanceEvaluations_main.log <==
'2014-01-24 08:47:50,112 [Thread-10] WARN module.ModuleDeclarationsFactory - 'grails.resources.modules' in config does not define any modules
' ==> catalina.out <==
Parsing DB Changelog
I don't see any error messages, only warnings. And all are harmless. For example the one about Ehcache is standard. If you don't provide a custom ehcache.xml, it defaults to one in the jar file and prints some messages to that effect. You can create your own - typically a modified version of the default file - and put it in the root of the classpath (non-Groovy files in grails-app/conf and src/java get copied to the classpath, so it's a good location) and it will be used instead. This is a good idea to do early on, even if you just keep the default values in your file, to make it easier to configure later. And the defaults are rather conservative, e.g. the TTL defaults to only 2 minutes.

How do disable log4j plugin in grails?

It appears the Grails 2.1 log4j plugin resets the log4j configuration during initialization of the grails application (see stack trace below).
at org.apache.log4j.LogManager.resetConfiguration(LogManager.java:233)
at org.apache.log4j.LogManager$resetConfiguration.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
at org.codehaus.groovy.grails.plugins.log4j.Log4jConfig.initialize(Log4jConfig.groovy:66)
at org.codehaus.groovy.grails.plugins.log4j.web.util.Log4jConfigListener.contextInitialized(Log4jConfigListener.java:48)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3910)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4389)
at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeployInternal(TomcatDeployment.java:313)
at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeploy(TomcatDeployment.java:145)
Is there any way to disable this "feature" or to remove this plugin altogether?
My JBoss server is already configured through jboss-log4j.xml and I do not want grails to make any changes to the configuration. I have already tried removing the log4j section of Config.groovy, but doing so had no effect.
As Kelly suggested, I have already removed all logging-related jars from my war file. Log4j classes are provided by JBoss.
EDIT I also tried the trick described in https://stackoverflow.com/a/1190438/539048 but that didn't seem to make any difference.
The solution was to remove the following section from the generated web.xml file:
<listener>
<listener-class>org.codehaus.groovy.grails.plugins.log4j.web.util.Log4jConfigListener</tag0:listener-class>
</listener>
To do so, I edited the scripts/Events.groovy file according to this blog but changed the listener class name to org.codehaus.groovy.grails.plugins.log4j.web.util.Log4jConfigListener.
eventWebXmlEnd = {String tmpfile ->
def root = new XmlSlurper().parse(webXmlFile)
def log4j = root.listener.findAll {node ->
node.'listener-class'.text() == 'org.codehaus.groovy.grails.plugins.log4j.web.util.Log4jConfigListener'
}
log4j.replaceNode {}
webXmlFile.text = new StreamingMarkupBuilder().bind {
mkp.declareNamespace("": "http://java.sun.com/xml/ns/j2ee")
mkp.yield(root)
}
}
Modify your BuildConfig.groovy like this:
inherits("global") {
excludes 'log4j', 'jcl-over-slf4j', 'slf4j-api', 'slf4j-log4j12'
}
This should remove all the logging libraries.
I tried the above suggestion on this grails application, so that I could expect to exclude the log4j dependencies of grails. However, after applying the suggestion, the jar files expected to be removed are still there in the generated war file. These jar files are: ./lib/grails-plugin-log4j-2.4.4.jar and ./lib/log4j-1.2.17.jar

Where can I find the Tomcat log written out by 'grails run-app'?

While running grails app in 'dev' mode using 'grails run-app', where is the default Tomcat log file located written out by the embedded Tomcat come with Grails (1.2.2) installation?
There isn't a default log file, the output to the log gets written to stdout.
Should be $CATALINA_HOME/logs/catalina.out
You have to define an log4j root logger in your Config.groovy like this:
log4j = {
appenders {
// console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
// file name:'file', file:'app.log'
}
// By default, messages are logged at the warn level to the console and the app.log
root {
warn 'stdout'
// warn 'stdout','file'
additivity = true
}
...
}
This example also shows how to configure the logging pattern. Also it shows how to configure file logging. The appenders section is optional and just needed to configure the logging pattern or file logger.

Resources