IMHO logging is the weakest point in application development, the Cinderella of IT.
Most people don't log enough information to enable effective troubleshooting, the context is lost, changing logging level in PROD is hell, if you enable debug level you end up being flooded with unwanted info, most of the time operators don't even have instructions on how to do it.
Besides one is interested in knowing what happened immediately before an error occurred, so one should always have like a Flight Recorder with some history preceding the error and ready to be dumped when this happens.
Also, frameworks like ByteBuddy or Btrace or AOP products allows you to dynamically define loggers... logging is a cross-cutting concern, it should not be interspersed in the business code cluttering it. Just define what to log in a separate module - configuration and convention over code.
Here at OverOps they seem to bring some value:
https://www.overops.com/java-monitoring
watch the short video:
Showing posts with label logging. Show all posts
Showing posts with label logging. Show all posts
Saturday, February 11, 2017
Monday, December 30, 2013
OSB, WebLogic and Logback / SLF4j
Being totally fed up with the OSB reporting provider, I am setting up logback.
Maven:
vi /opt/oracle/fmw11_1_1_5/wlserver_10.3/common/bin/commEnv.sh
add this to WEBLOGIC_CLASSPATH:
${CLASSPATHSEP}/opt/oracle/fmw11_1_1_5/wlserver_10.3/server/lib/slf4j-api-1.7.5.jar${CLASSPATHSEP}/opt/oracle/fmw11_1_1_5/wlserver_10.3/server/lib/logback-core-1.0.13.jar${CLASSPATHSEP}/opt/oracle/fmw11_1_1_5/wlserver_10.3/server/lib/logback-classic-1.0.13.jar
and copy the JARs:
cd /opt/oracle/fmw11_1_1_5/wlserver_10.3/server/lib/
this only if you have Nexus, otherwise.... copy them manually:
wget http://nexus.nespresso.com/service/local/repositories/adobe-ext/content/ch/qos/logback/logback-core/1.0.13/logback-core-1.0.13.jar
wget http://nexus.nespresso.com/service/local/repositories/adobe-ext/content/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.jar
wget http://nexus.nespresso.com/service/local/repositories/adobe-ext/content/org/slf4j/slf4j-api/1.7.5/slf4j-api-1.7.5.jar
vi /opt/oracle/domains/osbpl1do/config/osb/logback.xml
jconsole -J-Djava.class.path=C:\Oracle\MIDDLE~1\JDK160~1\lib\jconsole.jar;C:\Oracle\MIDDLE~1\JDK160~1\lib\tools.jar;C:\Oracle\Middleware\wlserver_10.3\server\lib\wlfullclient.jar -J-Djmx.remote.protocol.provider.pkgs=weblogic.management.remote -debug
and connect as:
service:jmx:iiop://myserver.acme.com:8001/jndi/weblogic.management.mbeanservers.runtime
The advantage is that I can also set programmatically the logger level for each logger, via JMX.
see here the doc, the first argument is the loggerName, the second is the level
A note: reloadByFileName() requires the FULL PATH : /opt/oracle/domains/osbpl1do/config/osb/logback.xml
Maven:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.0.13</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.13</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-parent</artifactId>
<version>1.0.13</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
vi /opt/oracle/fmw11_1_1_5/wlserver_10.3/common/bin/commEnv.sh
add this to WEBLOGIC_CLASSPATH:
${CLASSPATHSEP}/opt/oracle/fmw11_1_1_5/wlserver_10.3/server/lib/slf4j-api-1.7.5.jar${CLASSPATHSEP}/opt/oracle/fmw11_1_1_5/wlserver_10.3/server/lib/logback-core-1.0.13.jar${CLASSPATHSEP}/opt/oracle/fmw11_1_1_5/wlserver_10.3/server/lib/logback-classic-1.0.13.jar
and copy the JARs:
cd /opt/oracle/fmw11_1_1_5/wlserver_10.3/server/lib/
this only if you have Nexus, otherwise.... copy them manually:
wget http://nexus.nespresso.com/service/local/repositories/adobe-ext/content/ch/qos/logback/logback-core/1.0.13/logback-core-1.0.13.jar
wget http://nexus.nespresso.com/service/local/repositories/adobe-ext/content/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.jar
wget http://nexus.nespresso.com/service/local/repositories/adobe-ext/content/org/slf4j/slf4j-api/1.7.5/slf4j-api-1.7.5.jar
vi /opt/oracle/domains/osbpl1do/config/osb/logback.xml
<configuration debug="true" scan="true" scanPeriod="30 seconds">
<jmxConfigurator />
<property name="LOG_DIR" value="/opt/var/log/weblogic/server/" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder
by default -->
<encoder>
<pattern>%d %-5level [%thread] %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<appender name="GM"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}GM.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>GM.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>10</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>50MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<logger name="POC_LOG4j" additivity="false" level="INFO">
<appender-ref ref="GM" />
</logger>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
I provide a custom XPath to log :
package com.acme.osb.logging;
import org.apache.xmlbeans.XmlObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Used by OSB to report an Event
*
* @author NNVernetPI
*
*/
public class MessageTrackerSLF4J {
public static String logMessage(String technicalMessageid,
String businessId, String eventType, String interfaceName,
XmlObject payload) {
Logger projectLogger = LoggerFactory.getLogger(interfaceName);
StringBuilder sb = new StringBuilder();
if (projectLogger.isDebugEnabled()) {
sb.append(" ::InterfaceName:: ").append(interfaceName)
.append(" ::Payload:: ").append(payload.xmlText())
.append(" ::BusinessID:: ").append(businessId);
} else {
sb.append(" ::TechnicalMessageID:: ").append(technicalMessageid)
.append(" ::BusinessID:: ").append(businessId)
.append(" ::InterfaceName:: ").append(interfaceName)
.append(" ::EventType:: ").append(eventType)
.append(" ::ServerName:: ")
.append(System.getProperty("weblogic.Name"));
}
projectLogger.info(sb.toString());
String logmessage = "Info Message Logged for:: " + interfaceName;
return logmessage;
}
public static String errorLogger(String technicalMessageid,
String businessId, String interfaceName, XmlObject payload,
String priority, XmlObject fault) {
Logger projectLogger = LoggerFactory.getLogger(interfaceName);
StringBuilder sb = new StringBuilder();
sb.append("::TechnicalMessageID:: ").append(technicalMessageid)
.append(" ::InterfaceName:: ").append(interfaceName)
.append(" ::BusinessID:: ").append(businessId)
.append(" ::Payload:: ").append(payload.xmlText())
.append(" ::Priority:: ").append(priority)
.append(" ::FaultDescription:: ").append(fault.xmlText())
.append(" ::ServerName:: ")
.append(System.getProperty("weblogic.Name"));
projectLogger.error(sb.toString());
String responseMessage = "Error Message Logged for:: " + interfaceName;
return responseMessage;
}
}
which I expose as XPath this way:
<xpf:function>
<xpf:name>LOG_SLF_errorLogger</xpf:name>
<xpf:comment>logs an error</xpf:comment>
<xpf:namespaceURI>http://www.acme.com/acme2/xquery/xquery-functions</xpf:namespaceURI>
<xpf:className>com.acme.osb.logging.MessageTrackerSLF4J</xpf:className>
<xpf:method>java.lang.String errorLogger(java.lang.String, java.lang.String, java.lang.String, org.apache.xmlbeans.XmlObject, java.lang.String, org.apache.xmlbeans.XmlObject)</xpf:method>
<xpf:isDeterministic>false</xpf:isDeterministic>
<xpf:scope>Pipeline</xpf:scope>
<xpf:scope>SplitJoin</xpf:scope>
</xpf:function>
<xpf:function>
<xpf:name>LOG_SLF_messageTracker</xpf:name>
<xpf:comment>logs an event</xpf:comment>
<xpf:namespaceURI>http://www.acme.com/acme2/xquery/xquery-functions</xpf:namespaceURI>
<xpf:className>com.acme.osb.logging.MessageTrackerSLF4J</xpf:className>
<xpf:method>java.lang.String logMessage(java.lang.String, java.lang.String, java.lang.String, java.lang.String, org.apache.xmlbeans.XmlObject)</xpf:method>
<xpf:isDeterministic>false</xpf:isDeterministic>
<xpf:scope>Pipeline</xpf:scope>
<xpf:scope>SplitJoin</xpf:scope>
</xpf:function>
Since I have activated the jmxConfigurator, I can reload the logback.xml configuration file by connecting with JMX:
jconsole -J-Djava.class.path=C:\Oracle\MIDDLE~1\JDK160~1\lib\jconsole.jar;C:\Oracle\MIDDLE~1\JDK160~1\lib\tools.jar;C:\Oracle\Middleware\wlserver_10.3\server\lib\wlfullclient.jar -J-Djmx.remote.protocol.provider.pkgs=weblogic.management.remote -debug
and connect as:
service:jmx:iiop://myserver.acme.com:8001/jndi/weblogic.management.mbeanservers.runtime
The advantage is that I can also set programmatically the logger level for each logger, via JMX.
see here the doc, the first argument is the loggerName, the second is the level
A note: reloadByFileName() requires the FULL PATH : /opt/oracle/domains/osbpl1do/config/osb/logback.xml
Monday, December 6, 2010
SOA Suite - logging in BPEL
I was wondering how to log debug information in a BPEL process,
and here I found an excellent article on using a Java embedded action.... great stuff, Brazilian friend, bem feito!
Just code this into a Java Embedded activity:
This article seems to be interesting on how to use log4j from a BPEL process
See also here for more on logging XML in BPEL
and here I found an excellent article on using a Java embedded action.... great stuff, Brazilian friend, bem feito!
Just code this into a Java Embedded activity:
Object countLines = getVariableData("countLines");
System.out.println("IN LOOP countLines=" + countLines);
/* writes to the audit trail - will then be visible in BPEL console at runtime*/
addAuditTrailEntry("countLines is: " + countLines);
This article seems to be interesting on how to use log4j from a BPEL process
See also here for more on logging XML in BPEL
Subscribe to:
Posts (Atom)