I'm having a problem where logging works correctly when I run tomcat in non-forked mode from grails, but does not work correctly in forked mode.
Here is my Log4j configuration:
Config.groovy:
// log4j configuration
log4j = {
appenders {
file name:"fileLogger", file: "c:/logs/app-log.log", threshold: Level.DEBUG
}
debug fileLogger: ['com.foo', 'BootStrap']
info fileLogger: ['org.springframework']
error fileLogger: [
'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.hibernate',
'net.sf.ehcache.hibernate']
}
When I run grails run-app, the log file is correcly populated.
However, when I change my BuildConfig.groovy file to run tomcat in forked mode:
BuildConfig.groovy:
grails.project.fork = [
run: [maxMemory:1024, minMemory:64, debug:false, maxPerm:256]
]
The log file does not get populated.
Is there something wrong with my configuration? Why would it work in one mode, but not the other?
You have the threshold for the appender set to DEBUG level. I think in the forked tomcat mode the default level is set to INFO. In order to make it work for the forked mode you might need to increase the logging level to INFO and change DEBUGs to INFOs.
info fileLogger: ['org.springframework', 'com.foo', 'BootStrap']
Related
I'm trying to develop a grails 2.4.X plugin to add domain objects. When I run my application I get this in the application including the plugin:
Caused by CacheException: Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.
The source of the existing CacheManager is: DefaultConfigurationSource [ ehcache.xml or ehcache-failsafe.xml ]
->> 628 | assertNoCacheManagerExistsWithSameName in net.sf.ehcache.CacheManager
I assume that DataSource and Config (in the plugin) are over-written.
I updated the plugin to use to use BeanEhcacheRegionFactory4:
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = false
// cache.region.factory_class = 'net.sf.ehcache.hibernate.BeanEhcacheRegionFactory' // Hibernate 3
cache.region.factory_class = 'org.hibernate.cache.ehcache.BeanEhcacheRegionFactory4' // Hibernate 4
singleSession = true // configure OSIV singleSession mode
flush.mode = 'manual' // OSIV session flush mode outside of transactional context
}
Grails ehcache plugin - Another unnamed CacheManager already exists in the same VM
I don't have an ehcache.xml so I'm assuming it is using the groovy configuration.
Is this something that would be fixed by moving to 2.5 / 3?
Removing the ehcache plugin "fixes" this problem.
In my Grails project I've created and implemented log4j logging system.
In local environment file is correctly created, but in production server it is not.
here is the log4j configuration inside config.groovy file:
log4j = {
appenders {
file name: 'file', file:"/home/file.log"
}
root{
info 'stdout', 'file'
}
}
I've tried with other paths but it does not work.
How can I solve this issue?
I want to use send log messages to hourly rolling files in my grails application. Here is how I have configured log4j in Config.groovy
appenders {
rollingFile name:"stacktrace",
file: "/tmp/logs/app.log",
conversionPattern: '%-5p %d{MM-dd HH:mm:ss} %m (%F:%L)'
appender new DailyRollingFileAppender(
name: "events",
datePattern: "'.'yyyy-MM-dd-HH:mm",
file: "/tmp/logs/app_events.log",
layout: pattern(conversionPattern: "%c{2} %m%n")
)
}
root {
error 'stacktrace'
}
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.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.springframework'
info events: "com.app.events", additivity: false
This is how I'm getting logger for events within com.app.events package:
LOG = Logger.getLogger('events')
LOG.info("logging info")
I'm not sure what I'm missing here. I don't see any logs printed. If I add info 'events' inside root, it works but logs from all packages also go inside app_events.log which is not what I want. I only want logs from com.app.events package to go in app_events.log.
The parts of the logging instructions line in Config.groovy are:
// "Logging Level" "Appender Name": "Logger Name", "Other Options"
info events: "com.app.events", additivity: false
And in where you retrieve your logger:
// LOG = Logger.getLogger("Logger Name")
LOG = Logger.getLogger('events')
So to have the events appender receive package com.app.events logging, change how you retrieve your logger to:
LOG = Logger.getLogger('com.app.events')
Maybe using error 'stacktrace' in the root block is affecting log4j. The stacktrace appender is a special appender just for full stacktraces. Try adding another appender as your root appender and use that in place of 'stacktrace' in your root block.
appenders {
appender new DailyRollingFileAppender(
name: "base",
datePattern: "'.'yyyy-MM-dd-HH:mm",
file: "/tmp/logs/app_events.log",
layout: pattern(conversionPattern: "%c{2} %m%n")
)
}
root {
error "base"
}
I'm using Grails 2.3.5 and I need to pass an option to the forked JVM. I've tried doing this by setting the JAVA_OPTS environment variable, but that simply gets ignored by the forked JVM. How can I go about passing the forked JVM an option?
I've found this link, which is now dead: http://jira.grails.org/browse/MAVEN-177?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel but that's if you're using the Maven plugin I believe. I'm looking for the equivalent but without having to get Maven plugin involved.
According to: https://grails.github.io/grails2-doc/2.3.0/guide/single.html#forkedMode (near the bottom of the section) you can use jvmArgs in your grails.project.fork configuration. In BuildConfig:
grails.project.fork = [
// ...
run: [maxMemory:1024, minMemory:64, debug:false, maxPerm:256, jvmArgs: '..arbitrary JVM arguments..']
// ...
]
Couldn't post a comment. To clarify Andrew's answer, jvmArgs has to be a list.
grails.project.fork = [
// ...
run: [maxMemory:1024, minMemory:64, debug:false, maxPerm:256, jvmArgs: ['-Dsome.prop=true', ...] ]
// ...
]
Using Grails 2.5.1 in forked mode running with the Tomcat 7.0.55.3 plugin, I could not get any of the grails.project.fork.jvmArgs solutions to work.
I eventually was able to pass JVM options to the forked process by adding this at the end of my BuildGroovy.config:
grails.tomcat.jvmArgs = ['-jvm_option_here']
See: TomcatServerFactory.groovy
This seems pretty strange, but when grails builds a war file it doesn't generate a log4j.properties or log4j.xml file.
Instead it has the following in WEB-INF/web.xml
web.xml:
<listener>
<listener-class>org.codehaus.groovy.grails.web.util.Log4jConfigListener</listener-class>
</listener>
and apparently "grails Log4j DSL configures logging in-memory". The problem here is - log4j isn't automatically exposed to JMX for us to dynamically change and there's no log4j file generated by grails. But Config.groovy is a compiled file.
There's got to be an easy way to manage this without rebuilding the war?
One option suggested is go through to spring and configure logging there:
resources.groovy:
beans = {
log4jConfigurer(org.springframework.beans.factory.config.MethodInvokingFactoryBean)
{
targetClass = "org.springframework.util.Log4jConfigurer"
targetMethod = "initLogging"
arguments = ["classpath:myapp/log4j.properties"]
}
}
then shift the configuration in the DSL to the configured file.
Can anyone advise the 'groovy' way to dynamically change logging configuration without rebuilding the WAR file each time. Using grails-1.3.7. Cutting the DSL out doesn't seem the right way.
Thanks
You may have an external config file that is searched for by your application at startup time.
You would have a MyExternalConfig.groovy file somewhere in your production environment. For example:
log4j = {
def catalinaBase = System.properties.getProperty('catalina.base')
if (!catalinaBase) catalinaBase = '.'
def logDirectory = "${catalinaBase}/logs"
appenders {
rollingFile name:"infoLog", maxFileSize:'900KB', file:"${logDirectory}/${appName}Info.log", maxBackupIndex:10, layout:pattern(conversionPattern: '%d{DATE} %p %c - %m%n'), threshold: org.apache.log4j.Level.INFO
rollingFile name:"erroLog", maxFileSize:'900KB', file:"${logDirectory}/${appName}Erro.log", maxBackupIndex:10, layout:pattern(conversionPattern: '%d{DATE} %p %c - %m%n'), threshold: org.apache.log4j.Level.ERROR
}
root {
info 'infoLog', 'erroLog'
additivity = false
}
error erroLog:"StackTrace"
error erroLog: 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'net.sf.ehcache.hibernate'
warn infoLog: 'org.mortbay.log'
info infoLog: "grails.app"
}
Then in your Config.groovy file, that belongs to your grails project in conf folder, you put this as the last thing of the file:
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 configuration file defined."
}
This will look for external configurations files to add to your grails.config.locations attribute of your Config.groovy. First it looks for it as a System Environment variable (I use it this way), if it does not find, then it looks for a command line parameter (so you could add it when you start your tomcat app, as a parameter to startup.sh).
To configure your system environment variabble, just do this before starting tomcat:
MY_EXTERNAL_CONFIG="/home/tomcat/configs/MyExternalConfig.groovy"
export MY_EXTERNAL_CONFIG
--- start tomcat here ---
That's it.