I'm deploying a 2.3.5 Grails application with mysql in PCFDev. Hitting some URLs in my application I get a 500 error. When I view the logs with cf logs my-sample I only see access logs. They don't show my stacktrace.
How can I actually see the stacktrace in the logs so that I know exactly what is causing the error? Usually when deploying the app in Tomcat, I would see these logs in /logs directory of Tomcat.
This is what my config.groovy looks like for my grails application.
def catalinaBase = System.properties.getProperty('catalina.base')
if (!catalinaBase) catalinaBase = '.' // just in case
def logDirectory = "${catalinaBase}/logs"
log4j = { root ->
appenders {
// console name: 'stdout', layout: pattern(conversionPattern: "%d [%t] %-5p %c %x - %m%n")
rollingFile name:'stdout', file:"${logDirectory}/my.log".toString(), maxFileSize:'100KB'
rollingFile name:'stacktrace', file:"${logDirectory}/my_stack.log".toString(), maxFileSize:'100KB'
}
warn 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails.web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework',
'org.hibernate'
debug 'com.aerstone.ldap', 'com.aerstone.scanner.helper'
root.level = org.apache.log4j.Level.INFO
}
Googling "cf logs" brings up http://docs.pivotal.io/pivotalcf/1-8/devguide/deploy-apps/streaming-logs.html as the first result. It has a section on "Writing to the Log from Your App". It says:
Your app must write logs to STDERR or STDOUT. Both are typically buffered, and you should flush the buffer before delivering the message to Loggregator.
In addition to writing to a directory or file, you should consider also sending that output to STDOUT and STDERR streams as per the Twelve-Factor App treatment of logs.
Also, you can search "cf ssh" which gives this result explaining how you can SSH into your apps' containers and look at things on their local file system.
Related
I am trying to log4j log (info and debug) in a separate file in /logs/mylog.log. I have created "logs/mylog.log under WEB-INF in my Grails project's folder structure. I also add appenders in Config.groovy. Below is my log4j entry inside log4j = {} in my config.groovy.
appenders {
console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
file name:'grailslog', file:'/logs/mylog.log', threshold:org.apache.log4j.Level.DEBUG, org.apache.log4j.Level.INFO
}
root { debug 'stdout', 'file' }
error 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails.web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework',
'org.hibernate',
'net.sf.ehcache.hibernate',
'com.test'
info 'com.test.nip'
//trace 'org.hibernate.type'
debug 'org.hibernate.SQL'
debug 'com.test.nip.pacs'
environments {
production {
debug 'com.test',
'org.springframework.security'
}
}
but here I am getting file not found error for '/logs/mylog.log' when I start my server.
When you refer to the log file with the path /logs/mylog.log you are using an absolute path in the system your server is installed, it odes not mean it is under WEB-INF also putting a log file under WEB-INF is good idea because the file will be deleted as you deploy a new war.
Possible Solution:
Create the /log directory under the sytem root.
Make sure the server process has enough permission to create and write into the /log directory. If it does not, grant it permissions.
How to add a rolling file appender?
rollingFile name: "file",
maxFileSize: 5000000,
file: "/log/mylog.log",
threshold: org.apache.log4j.Level.DEBUG
It is thoroughly documented in the official doc.
If we deploy our Grails application in a JBoss 4.3, it always shows the same error message:
ERROR: invalid console appender config detected, console stream looping
In the Config.groovy file we have defined the log4j:
log4j = {
root {
info 'unoAppender','communications', 'hibernate', 'dependencies'
}
appenders {
appender new CustodianDailyRollingFileAppender(
name:'unoAppender',
file:'logs/app-uno.log',
append:true, maxNumberOfDays:60,
compressBackups:true,
threshold:Level.DEBUG,
layout: pattern(conversionPattern: "%d{ISO8601} %-5p [%t:%1X{JSESSION_ID}] [%c{1}] - %m%n"))
.....
}
}
And also there are appenders in the jboss-log4j.xml of the default server.
Finally we have tried to add the following paramenter in the JAVA_OPTS of the run.sh [-Dorg.jboss.logging.Log4jService.catchSystemOut=false] the logs works properly in the console but it does not work in the server.log.
When I launch my grails application, I get the following error:
java.io.FileNotFoundException: stacktrace.log (Permission denied)
I know this can be solved by chowning some files/directories or by changing the file the logs go to, but I don't want this: I just want stracktraces to be logged to the stdout.
The documentation states:
For example if you prefer full stack traces to go to the console, add
this entry:
error stdout: "StackTrace"
However: it also states:
This won't stop Grails from attempting to create the stacktrace.log
file - it just redirects where stack traces are written to.
And later:
or, if you don't want to the 'stacktrace' appender at all, configure
it as a 'null' appender:
log4j = {
appenders {
'null' name: "stacktrace"
}
}
I combine the 2 and get the following configuration:
// log4j configuration
environments {
production {
log4j = {
appenders {
console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
// Don't use stacktrace.log
'null' name: "stacktrace"
}
}
}
}
log4j = {
// print the stacktrace to stdout
error stdout:"StackTrace"
}
Unfortunately, this doesn't work:
INFO: Deploying web application archive MyBackend.war
Sep 12, 2012 4:46:11 PM org.apache.catalina.core.StandardContext start
SEVERE: Error listenerStart
Sep 12, 2012 4:46:11 PM org.apache.catalina.core.StandardContext start
SEVERE: Context [/MyBackend2] startup failed due to previous errors
Admittedly, it doesn't attempt to write stacktrace.log anymore, so the Permission denied error isn't thrown anymore, but I have no clue why the app won't start becaue the only thing it logs is "Error listenerStart"
Can anyone please help me with configuring my app to just log the stacktraces to stdout?
Grails Bug report:
http://jira.grails.org/browse/GRAILS-2730
(contains some workarounds)
If you want stacktraces to stdout:
log4j = {
appenders {
console name:'stacktrace'
...
}
...
}
Disable stacktrace.log:
log4j = {
appenders {
'null' name:'stacktrace'
...
}
...
}
stacktraces to application specific log file in Tomcat logs directory
log4j = {
appenders {
rollingFile name:'stacktrace', maxFileSize:"5MB", maxBackupIndex: 10, file:"${System.getProperty('catalina.home')}/logs/${appName}_stacktrace.log", 'append':true, threshold:org.apache.log4j.Level.ALL
...
}
...
}
kudos to this blog post: http://haxx.sinequanon.net/2008/09/grails-stacktracelog/
Here is what I have to deal with this:
log4j = {
appenders {
// Be smart if we are running in tomcat or not
String logDir = Environment.warDeployed ?
System.getProperty('catalina.home') + '/logs' :
'target'
// Handle the stacktrace log correctly
rollingFile name:'stacktrace',
maxFileSize: "5MB",
maxBackupIndex: 10,
file: "${logDir}/${appName}_stacktrace.log",
layout: pattern(conversionPattern: "'%d [%t] %-5p %c{2} %x - %m%n'"),
'append': true,
threshold: org.apache.log4j.Level.ALL
}
}
This lets us gracefully handle being deployed as a WAR in Tomcat, as well as in development. It also has the advantage of allowing multiple grails applications to run within the same container without mushing all of their stacktrace logs together.
Inspiration for this comes from #FlareCoder's answer above, as well as from #BurtBeckwith's mailing list post.
I've been using the javamelody monitoring plugin for a while in Grails with no problem, but lately I had to move my developments to another computer (I'm now using netbeans 7.1.2). After reinstalling the plugins, I run the app flawlessly in my development environment. But when I run the war to my production environment, the following warnings show up:
log4j:WARN No appenders could be found for logger (net.bull.javamelody).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
The appenders section in Config.groovy is:
appenders {
console name:'stdout', layout:pattern(conversionPattern: '%d [%t] %-5p %c{2} %x - %m%n')
appender new DailyRollingFileAppender (
name: 'dailyAppender',
datePattern: "'.'yyyy-MM-dd",
fileName: "logs/${appName}.log",
layout: pattern(conversionPattern:'%d [%t] %-5p %c{2} %x - %m%n')
)
}
My questions are:
Why aren't these warnings present in the development environment's log ?What are possible consecuences on the application ?
I'm running Grails 1.3.9, Melody 1.2, tomcat 7.0.23
Thanks
It might be different form environment to environment if you have
setup a logging appender in the development section of your Grails
Config.groovy file but not for your production section.
The consequences are that you will not have logging. You may have code in your application that says log.error("Critical Error!") but since this is not linked to any appender you will never see it anywhere.
Check out logging in the documentation.
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.