How to append grails logging using profiler into custom appender(log file)? - grails

Using grails profiler plugin, I want to append logging into separate file only for profiler.

You should be able to create an appender and then set the appropriate logger (looks to be com.linkedin.grails) to append to it with additivity set to false.
grails 3.x:
appender("PROFILER", FileAppender) {
file = "profiler.log"
encoder(PatternLayoutEncoder) {
pattern = "%level %logger - %msg%n"
}
}
logger("com.linkedin.grails", DEBUG, ["PROFILER"], false) // false here is for additivity
grails before 3:
file name: 'profiler', file: 'profiler.log', layout: pattern(conversionPattern: '%d{[yyyy-MM-dd HH:mm:ss.SSS]} [%t] %-5p: %c %x - %m%n')
debug profiler: [
"com.linkedin.grails"
], additivity: false

Related

Debug statements aren't showing src/groovy classes

I have the following in my config.groovy
// default for all environments
log4j = { root ->
appenders {
rollingFile name:'stacktrace', file:"${logDirectory}/app_stack.log".toString(), maxFileSize:'100KB'
}
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'
debug 'com.my.code'
root.level = org.apache.log4j.Level.INFO
}
I get debug statements printed to the logs for all classes except for my groovy files placed in package com.my.code I don't get the debug statements printed. Only the info statements are being printed to the log.
Here is an example for one of the groovy classes in src/groovy
#Log4j
class SomeTest {
def someMethod() {
log.info("This will print")
log.debug("This will not print")
println log.isDebugEnabled() //prints false
print log.isInfoEnabled() //prints true
}
}
Question
How can I turn on debugging for all class under package com.my.code ? I'm on grails 2.3.5. When I change root.level to org.apache.log4j.Level.DEBUG then the debug statements do show up but that turns on DEBUG for ALL other classes as well
Here's a configuration that will log all code in packages com.my.code at the DEBUG level, and all other packages at the ERROR level.
The logs will be sent to the console and a file named appLog.txt.
log4j = {
appenders {
def logPattern = '%d{dd-MM-yyyy HH:mm:ss,SSS} %5p %c{2} - %m%n'
console name: 'consoleAppender', layout: pattern(conversionPattern: logPattern)
file name: "fileAppender", file: "appLog.txt"
}
root {
// define the root logger's level and appenders, these will be inherited by all other loggers
error 'consoleAppender', 'fileAppender'
}
def appNamespaces = [
'com.my.code',
'grails.app.conf.com.my.code',
'grails.app.filters.com.my.code',
'grails.app.taglib.com.my.code',
'grails.app.services.com.my.code',
'grails.app.controllers.com.my.code',
'grails.app.domain.com.my.code'
]
appNamespaces.each { debug it }
}
In grails 2.x apps I used next format (with regards to your config):
debug rollingFile 'com.my.code'
Furthermore, if you need to set different log level for a bunch of packages:
debug rollingFile: ['com.example','com.otherpackage']

Grails logging from controller

I'm having a hard time to get Grails 2.4.5 to log my custom messages from my controllers into a specific file. This is what I have in the config part:
log4j = {
/*
* Log levels
off
fatal
error
warn
info
debug
trace
all
*/
appenders {
console name:'stdout', threshold: org.apache.log4j.Level.INFO
rollingFile name: 'applog', maxFileSize: 1024, file: (System.getProperty('catalina.base') ?: 'target') + '/logs/' + appName + '.log',
layout: pattern(conversionPattern: "[%d{HH:mm:ss:SSS}] %-5p %c{2}: %m%n")
environments {
development {
rollingFile name: 'grailsfile', maxFileSize: 4096, file: 'target/logs/grails.log'
file name: 'rootlog', file: 'target/logs/root.log'
}
}
}
root { error 'stdout'}
environments {
development {
debug additivity: false, 'grails.app'
root { error 'stdout', 'rootlog'} //override the root
warn additivity: false, grailsfile:
['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']
debug additivity: false, applog:
['grails.app.controllers', 'grails.app.domain', 'grails.app.services']
}
// production {
// root { error() }
// warn "grails.app.controllers"
// warn "grails.app.domain"
// warn "grails.app.services"
// warn additivity: false, applog: 'grails.app'
// }
}
}
in the controller:
println "Debug log enabled?: " + log.debugEnabled
log.debug "First piggy wrote to Debug"
log.info "Second piggy wrote to Info"
log.error "And the third piggy wrote to Error"
That shows me "Debug log enabled?: true" on console. But the message are not logged anywhere.
The Grails internals log to "grailsfile" and also errors go to "rootlog". But appName.log stays empty.
Any hint what I am having wrong?
UPDATE
To simplify my request I have only configured the most important now. I want the lines
log.debug "First piggy wrote to Debug"
log.info "Second piggy wrote to Info"
log.error "And the third piggy wrote to Error"
End up in the appender applog (file)
So the log4j now only has:
log4j = {
appenders {
console name:'stdout'//, threshold: org.apache.log4j.Level.INFO
rollingFile name: 'applog', maxFileSize: 1024, file: (System.getProperty('catalina.base') ?: 'target') + '/logs/' + appName + '.log',
layout: pattern(conversionPattern: "[%d{HH:mm:ss:SSS}] %-5p %c{2}: %m%n")
}
environments {
development {
debug 'grails.app'
debug additivity: false
applog: ['grails.app.controllers', 'grails.app.domain', 'grails.app.services']
}
}
}
But Still I get my log lines (and also errors from other sources) into console while my custom log file stays empty.
So I simply want to get (ONLY) my log lines into the applog appender as a first step. Any hint how to achieve this?
If you are running the app in development mode, then all your logs with error level and higher are going to target/logs/root.log
It is configured here:
file name: 'rootlog', file: 'target/logs/root.log' ...
root { error 'stdout', 'rootlog'} //override the root
That's because development closure overrides your global configuration.
If you want to see all the logs in appName.log, you should set lower logging level and change appender like this:
root { info 'stdout', 'applog'} //override the root
meanwhile I could figure out that this property made the trouble for my custom log messages:
def appName = grails.util.Metadata.current.'app.name'
...
file: (System.getProperty('catalina.base') ?: 'target') + '/logs/' + appName + '.log',
changing to this works:
log4jFileName = (System.properties.'catalina.base') + "/logs/${appName}.log"
...
file: "${config.log4jFileName}",

Log4j2 Grails RollingFileAppender

I'm trying to implement log4j2 with grails 2.5.3 and I'm having problems with the configuration properties.
I my older projects with log4j 1.x I used to have in the config.groovy file something like this:
import org.apache.log4j.*
...
log4j={
environments{
production{
appenders{
def rollingAppender = new RollingFileAppender(
name: "rollingAppender",
layout: pattern(conversionPattern:"[%p] %d{yyyy-MM-dd HH:mm:ss.SSS} (%t) %c{2} %X - %ms : %m%n"),
file: "/tmp/logs/catalina.out",
bufferedIO: false,
maxFileSize: "300MB"
)
appender rollingAppender
}
}
development{
appenders {
def rollingAppender = new RollingFileAppender(
name: "rollingAppender",
layout: pattern(conversionPattern:"[%p] %d{yyyy-MM-dd HH:mm:ss.SSS} (%t) %c{2} %X - %ms : %m%n"),
file: "/tmp/logs/catalina.out",
bufferedIO: false,
maxFileSize: "15MB"
)
appender rollingAppender
}
}
}
info aditivity:false, rollingAppender:"grails.app.services"
info aditivity:false, rollingAppender:"grails.app.controllers"
}
Now, I have seen XML configuration files everywhere but I can't find the way to do it like I used to. I mean, I want to load different configs depending on the enviroment the application is running. Is it a possibility with log4j2?
I have something like this now:
import org.apache.logging.log4j.core.appender.RollingFileAppender
import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy
import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy
import org.apache.logging.log4j.core.layout.PatternLayout
...
enviroments{
development{
appenders {
def rollingAppender = new RollingFileAppender(
name: "rollingAppender",
filePattern: "/tmp/logs_bkp/catalina.%d{yyyy-MM-dd HH:mm:ss.SSS}.log.gz",
layout: new PatternLayout("[%p] %d{yyyy-MM-dd HH:mm:ss.SSS} (%t) %c{2} %X - %ms : %m%n")
fileName: "/tmp/logs/catalina.out",
bufferedIO: false,
policy: new SizeBasedTriggeringPolicy(1024),
strategy: new DefaultRolloverStrategy(2,1,"min",false,5)
)
appender rollingAppender
}
}
}
I know it has some errors, but I can't figure it out how to make it work without using the XML config file. Any ideas?

How do I set up a log4j appender with 'appender-ref' in grails 2?

Using the Grails config DSL, how can I configure the appender-ref property on an appender?
I am trying to translate a log4j.xml from perf4j into the Grails config DSL (Grails 2.x).
In the log4j.xml file that I am trying to imitate, there is a segment like this:
log4j.xml
<appender name="CoalescingStatistics"
class="org.perf4j.log4j.AsyncCoalescingStatisticsAppender">
<param name="TimeSlice" value="10000"/>
<appender-ref ref="fileAppender"/>
</appender>
I want to imitate this appender's config in Grails, but I can't figure out the <appender-ref> tag.
Here is my latest attempt:
log4j = {
appenders {
//main appender for the app
rollingFile ...
//perf4j coalescing stats appender
appender new AsyncCoalescingStatisticsAppender(name: "coalescingStatsAppender", timeSlice: 10000)
//perf4j stats file appender
rollingFile name: "perfLogFileAppender", file: "perfStats.log", layout: new PatternLayout("%m%n")
}
root {
error 'stdout', 'rollingFileAppender'
}
info additivity: false, coalescingStatsAppender: [StopWatch.DEFAULT_LOGGER_NAME]
}
Additional details
Here is the source log4j.xml I am imitating:
https://web.archive.org/web/20150508124059/http://perf4j.codehaus.org/devguide.html#Using_the_log4j_Appenders_to_Generate_Real-Time_Performance_Information
I was able to make it work with some Groovy magic:
log4j = {
appenders {
//...regular appenders
//perf4j appenders
Appender perfLogFileAppender = delegate.rollingFile name: "perfLogFileAppender", file: "perfStats.log", layout: new PatternLayout("%m%n")
def statsAppender = new AsyncCoalescingStatisticsAppender(name: "coalescingStatsAppender", timeSlice:
10000)
statsAppender.addAppender(perfLogFileAppender)
appender statsAppender
}
root {
error 'stdout', 'rollingFileAppender'
}
info additivity: false, coalescingStatsAppender: [StopWatch.DEFAULT_LOGGER_NAME]
}
A more elegant solution is always welcome.

Import external config value into main config in grails

I have an external config file ${userHome}/.grails/${appName}/config.groovy:
package configs
grails.conf.logDirectory = '/home/serek/tmp/mamlog'
which I would like to import into main grails Config.groovy
grails.config.locations = ["file:${userHome}/.grails/${appName}/config.groovy"]
print grails.conf.logDirectory
log4j = {
appenders {
rollingFile name: 'infoLog', file: "${grails.conf.logDirectory}/info.log", threshold: org.apache.log4j.Level.INFO, maxFileSize: "1024MB", append: true
rollingFile name: 'warnLog', file: 'warn.log', threshold: org.apache.log4j.Level.WARN, maxFileSize: "1024MB", append: true
console name: 'stdout', layout: pattern(conversionPattern: '%d{yyyyMMdd.HHmmss.SSS} %r [%t] %-5p %c %x - %m%n')
}
Unfortunately, print grails.conf.logDirectory is not visible in main config.
How can I handle that? Print outputs only [:]
Groovy: 2.1.9
Grails: 2.3.2
========================================
I found solution, ex Config.groovy:
import org.yaml.snakeyaml.Yaml
Yaml yaml = new Yaml()
def extConfFilePath = "${userHome}/.grails/${appName}/mam.yaml" //my external conf in yaml
def extConfFileContent = new File(extConfFilePath).text
def extConf = yaml.load(extConfFileContent)
grails.ext = extConf
rollingFile name: 'infoLog', file: extConf.logDirectory + "info.log", threshold: org.apache.log4j.Level.INFO, maxFileSize: "1024MB", append: true
I believe its because the external config files are pulled in after Config.groovy is executed. Therefore, println at that location doesn't work. Try printing it from any gsp page with,
println "logDir = ${grailsApplication.config.grails.conf.logDirectory}"

Resources