Google App Engine - log messages not visible - java

I have a Spring boot application deployed to GCP App Engine with logback as a logging framework. The problem which I am facing is that I can not find the logger messages which I put into my code. I found a similar post: Google App Engine - Can not find my logging messages. But it is pretty much older and the solutions are not working anymore. On this post, it is mentioned to set the logger level manually. On a similar line, I used logging.properties file to set the level as INFO. But still, it was of no use.
I thought the issue might be with the file permission on the App Engine. So, I specified the log file location at /tmp having full read-write permissions. It did not work. If there are any exception scenarios then stack traces are visible on Stackdriver Logging. Please suggest.

Here is how I managed to make the logs appear in Stackdriver under java.log.
I created a file myApp/src/main/resources/logback.xml and added this configuration:
<configuration>
<appender name="STDOUT" class="com.google.cloud.logging.logback.LoggingAppender">
</appender>
<root level="info">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
I also added the dependency in the file myApp/pom.xml :
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-logging-logback</artifactId>
<version>0.80.0-alpha</version>
</dependency>
<!-- other dependencies -->
</dependencies>
Then in my main.java I did logger.info("my info log") and logger.error("my error log") and the logs appeared in Stackdriver after a few seconds of accessing my web app.
I took the sample code from the GoogleCloudPlatform/getting-started-java repository to deploy my app.

Related

How do I set up log4j2 in an Alexa skills maven project?

I'm developing an Alexa skill using Java to handle the intents.
The Java project is a maven project. One of the dependencies is on Apache's log4j2.
Here's a snapshot of the log file from my last test. I wish Amazon would allow you to download logs. Edited: I found a way to copy and paste part of the log.
START RequestId: 5077a4b9-f3ad-49f9-9f79-0c78e443bf41 Version: $LATEST
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. Set system property 'org.apache.logging.log4j.simplelog.StatusLogger.level' to TRACE to show Log4j2 internal initialization logging.
END RequestId: 5077a4b9-f3ad-49f9-9f79-0c78e443bf41
REPORT RequestId: 5077a4b9-f3ad-49f9-9f79-0c78e443bf41 Duration: 2117.38 ms Billed Duration: 2200 ms Memory Size: 512 MB Max Memory Used: 155 MB Init Duration: 3143.46 ms
START RequestId: d3bff3f0-a270-4a02-8cbc-a2be3162741f Version: $LATEST
22:37:48.898 [main] ERROR com.ggl.bible.reader.ReadingTypeIntentHandler - Mode value: reading
22:37:48.916 [main] ERROR com.ggl.bible.reader.ReadingTypeIntentHandler - Reading decision value: reading
22:37:48.997 [main] ERROR com.ggl.bible.reader.ReadingTypeIntentHandler - Reading Decision reading not understood
END RequestId: d3bff3f0-a270-4a02-8cbc-a2be3162741f
I don't know if the image is clear enough, but the second line tells me that the log4j2 can't find the log4j2 configuration file.
I have a log4j.properties file in src/main/resources. It's not much, but it's all I need
log4j.rootLogger=INFO
As you can see from the image (I hope), lines 6 - 8 at 22:37:48 are logger output. For now, all of my logger output is written as ERROR. While this "works", I'd like to be able to distinguish the information from the actual error.
The first two logger lines are information. The third line is an actual error where Alexa didn't interpret the word as I would have liked.
I'd like to set up a working log4j properties file, and I'd like to know where the properties file is supposed to be placed in a maven project. Thanks for your help.
As requested in the comments, the Java class with the logger comments is too long to post in its entirety.
Here's the logger definition.
private static Logger logger = LogManager.getLogger(ReadingTypeIntentHandler.class);
Here's a few lines of logger methods.
if (modeValue.isPresent()) {
logger.error("Mode value: " + modeValue.get());
}
if (bookValue.isPresent()) {
logger.error("Book value: " + bookValue.get());
}
if (startChapterValue.isPresent()) {
logger.error("Start chapter value: " + startChapterValue.get());
}
The Java code works. The messages appear in the log file.
My pom dependency is here. If there's more than one needed, tell me what else I need. Maven isn't telling me I'm missing anything.
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
Edited again: Adding a pom dependency for log4j-api had no effect.
Adding a log4j2.xml file to src/main/resources got rid of the "No log4j2 configuration file found." message in the log. This was the practical answer for me.
Here's the log4j2.xml file I used. I hope this question helps future Alexa skills developers.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>

Logback logs kept open by application and not deleting from disk

I have an Spring-Boot application on Linux that writes to service logs using Logback. Logback is setup to write to a file (account-service.log) and rotate the file at 10.5MB and finally delete the file on the 8th rotate. This is the default configuration.
The issue I'm having is the first log file created is written to past the 10.5MB size limit (it does rotate at the 10.5MB mark). So it's increasing in size until it becomes the 8th file and then it tries to get deleted. At this point the file is 84MB (10.5MB * 8) size. You can see here the file increasing in size
The main problem with that is that the OS tries to delete the file but since the application, because of Logback, still keeps it open then the filesystem doesn't show the deleted file (like with command find or du) and the system still keeps the space allocated on the disk. Also the file is still written to so it's taking up more and more disk space. I ran sudo lsof | grep deleted to find out that this file isn't being fully deleted.
Also interestingly the group that that first file belongs to is different than the rest. The first file has group root while the rest have the correct group name of account-service. This might be why the application can't close the file but I'm not sure.
The Logback dependency comes from my Spring-Boot pom:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
The subsequent log files do get deleted ok and don't get written to past the 10.5 MB limit.
Has anyone seen this issue or found a way to fix it?
So I was able to solve most of my problems but one issue still remains.
The main issue was that I was using the built in logback xml for logging (base.xml). There it was configured for both console and file logging to be enabled.
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
So when I run it locally I get my logs written to my terminal and service log file which is good but the issue occurs on deployed instances. What happened was that both "CONSOLE" and "FILE" loggers where writing to the file which is why even after the first file rotated, it was still being written too. The "CONSOLE" logger was writing to the first file even though it rotated because from its point of view that file is the terminal. This also helped fix a double logging issue we were seeing.
My fix was to add my own logback xml (logback-spring.xml) to override the base.xml one.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<springProfile name="default">
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</springProfile>
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<root level="INFO">
<appender-ref ref="FILE" />
</root>
This stops console logging on deployed instances and thus keeps the first file from logging past the 10.5MB limit. This fix fixed the disk space issue we experienced too.
The only issue I was not able to solve yet it why the file is kept open by the application and thus not allowing it to be fully deleted from the disk space.
As you have mentioned the file as root user access permissions which do not look correct. Can you check the application by doing ps -efw | grep applicationName to see what user permissions it has as your application should have application user permissions only.

ERROR StatusLogger No log4j2 configuration file found. While updating the version 2.5.12 of Struts

As per the requirement and for security purpose I am updating Struts project. Before the Struts version is 2.3.24 and now I am updating it to 2.5.12. I have downloaded all the required jar files of Struts and applied to project but I am getting the below error
ERROR StatusLogger No log4j2 configuration file found. Using default
configuration: logging only errors to the console. Set system property
'org.apache.logging.log4j.simplelog.StatusLogger.level' to TRACE to
show Log4j2 internal initialization logging.
But I am not using any logger in my project. I have added all the dependency jar files and I am not using Maven, but added related libraries in lib folder. Any suggestions please.
Struts framework is using a logging framework log4j second version.
Struts 2.3 to 2.5 migration
Please be aware that the framework is using Log4j2 now as a main logging layer, the existing old logging layer is deprecated and will be removed soon. Log4j2 supports many different logging implementations, please check documentations for more details.
The file log4j2.xml is required to bootstrap the logging framework. But it's missing from the classpath. It's also missing from the Struts framework.
You should find some log4j2.xml, i.e. from the struts-showcase application or read a step 4 in this tutorial How To Create A Struts 2 Web Application
Step 4 - Add Logging
To see what’s happening under the hood, the example application for this tutorial uses log4j2. You’ll need to add a dependency node for log4j2 to the pom:
pom.xml log4j dependency node
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
Using both log4j-core and log4j-api allows to use the latest version of Log4j2 without a clash with version provided by the framework. Setup a log4j2.xml configuration in the src/main/resources folder which contains the following
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.opensymphony.xwork2" level="debug"/>
<Logger name="org.apache.struts2" level="debug"/>
<Root level="warn">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
Note the above log4j2 configuration specifies the console as the log target.
No log4j2 configuration file found means log4j2.xml configuration file is not in your classpath.
Check your project jar contains log4j confuguration file or not.
Otherwise you can set log4j confuguration file path as system property in your build script.
<sysproperty key="log4j.configurationFile" value="file:///${basedir}/src/log4j2.xml" />
Check https://logging.apache.org/log4j/2.x/manual/configuration.html for log4j configuration

Components written against log4j1 are not logging after log4j2 upgrade

I've been banging my head over this one for a few days and can't get it figured out. Log4j2 is backwards compatible if you add the log4j1 compatibility library.
My web-inf\lib has:
slf-api
log4j-1.2-api (backwards compat. library)
log4j-api (log4j2)
log4j-core (log4j2)
log4j-web (auto-wiring for web applications)
My web.xml has:
<!-- log4j2 auto-wiring -->
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>file:///${catalina.base}/conf/log4j2.xml</param-value>
</context-param>
My [tomcat]/conf/log4j2.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
<!-- Appends to CONSOLE -->
<Console name="consoleAppender" target="SYSTEM_OUT">
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY" />
<PatternLayout pattern="%5p (%F:%L) - %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="com.mycompany.componentA" level="WARN" />
<Logger name="com.mycompany.componentA.QueryLogger" level="DEBUG" />
<Logger name="com.mycompany.mycode" level="DEBUG" />
<Root level="WARN">
<AppenderRef ref="consoleAppender" />
</Root>
</Loggers>
</Configuration>
I have upgraded code under my control (com.mycompany.mycode) to log4j2 APIs and they work/log flawlessly. Code that is not under my control but was written against log4j1 (com.mycompany.componentA) just simply fails to log at all. No errors, no debugs, nothing.
Something interesting though... when I start the application I get a log4j1 warning about incorrect configurations when the application starts. This also stumps me because there are no log4j1 libraries (except the compatibility API) in the WAR. Warning is:
log4j:WARN No appenders could be found for logger (com.mycompany.componentB)
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
EDIT: I (finally) figured out what's going on. One of my dependencies did a horribly bad thing and BUNDLED the log4j1 classes into it's final jar. So there are no log4j1 jars on the classpath, but there are log4j1 CLASSES on the classpath.
The only way I was able to get this working was to:
Create BOTH a log4j1 and log4j2 XML configuration files (even though the log4j2 configuration contained all the loggers I wanted)
Let Log4j2 auto-wire itself via the 'log4j-web' artifact + 'log4jConfiguration' web.xml parameter
Manually wire log4j1 by calling the deprecated Log4jConfigurer.initLogging(...) API on server startup
This is probably horribly incorrect, but as indicated above, it was the only way I got it working after weeks of fooling around.
My understanding of the lo4j1 bridge is that wiring up log4j2 and including the bridge is all that should be required (e.g. no need to manually wire log4j1). In practice, that does not seem to be occurring.
That error message means you still have the log4j-1.x jar in your application. Look for it in your WEB-INF/lib and remove it and then it should work.
If not in WEB-INF/lib, then perhaps in your web container (Tomcat?) shared lib folder? Ralph is right that this error message is generated by Log4j-1.2, so it is on the classpath somewhere... Try printing the value of System property java.class.path if necessary.
Update: another way to find the location of the Log4j1 jar is by printing the value of org.apache.log4j.AppenderSkeleton.class.getResource("/org/apache/log4j/AppenderSkeleton.class") from your application.
(I originally suggested Category but this also exists in the Log4j 1 bridge, so AppenderSkeleton is better.)

Prevent Spring Boot from printing logs to console

I am using spring boot for my application and I am using default spring boot logging.
In my application.properties, I have added file path for logging.file,
logging.file= ${logger_path}
and my pom.xml contains
<logger_path>/tmp/app.log</logger_path>
When I start the application, it prints the logging messages to the file at /tmp/app.log, but the problem is it also prints the log messages on the console. I really don't understand why it is printing on console (though it is printing them to the specified file) when I have specified a log file.
Is there any configuration to prevent spring boot from printing the log messages to console?
Spring boot comes with build-in logback logger, which is configured to print to the console by default.
You need to overwrite the logback configuration (providing your own logback.xml on the classpath).
This is described here - - section 66.1
How to disable logback logging read here -
as you can see you have to provide the value OFF...something like:
<configuration>
<include resource="base.xml" />
.
.
<property name="root.level.console" value="OFF" />
</configuration>
Note: Keep in mind that the general idea here is that the logback configuration coming from spring-boot is minimal. The intention is that you provide your own logback configuration and completely overwrite the existing one - e.g. providing your own logback configuration with only log file-appender configured - this should be your general approach.
Include file-appender.xml and not console-appender with following configuration in logback-spring.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
You also need to add logging.file to your application.properties
This is in compliance to what is mentioned in spring boot documentation - http://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html
I tried removing console configuration from logback.xml. But, It was still logging in console. So What I did is, I just removed the appender being added in the logging configuration by springboot. Thereby, we can stop springboot logging in console and separate log file. Add the below lines at the end of your application specific appenders are added. Your custom appender should not match any of these appender names. It worked for me.
// get instance of your log4j instance
Logger logger = LogManager.getRootLogger();
logger.removeAppender("CONSOLE"); // stops console logging
logger.removeAppender("LOGFILE"); // stops file logging
A similar discussion can be found here.
My logback.xml looks like that:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
Just in case you still experience an issue: I have read many discussions about that topic and it was not working at all for me. Unfortunately I have made a really stupid mistake when I have created the file logback.xml for the very first time: A space was added at the beginning of the filename. Therefore the file was never used. So just have another look on the filename, add the file in "src/main/resources" and remove any "logging.config" entries from your property files.
Tested with latest 1.3.1 release, with newer releases base.xml has been renamed to defaults.xml
Answer here

Categories

Resources