Configure logging with Lift - scala

The Lift wiki page on logging states that a lot of setup is done automatically. Right now my problem is that I already have a running backend with its own logging configuration and a log4j.properties file in my classpath which should be used. There are also dependencies to log4j and SLF4j already in the classpath.
The main problem is that I get complete debug output for everything. Hibernate in particular -- which is very annoying.
I am using Lift 2.3-M1 and tried doing the following in the beginning of boot():
Logger.setup = Full(Log4j.withFile(getClass().getResource("/props/log4j.xml")))
The log4j.xml I am currently using is quickly hacked together to simply suppress DEBUG output.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration threshold="info" xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="CA" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%p] %c{2} %m%n"/>
</layout>
</appender>
<root>
<level value="info"/>
<appender-ref ref="CA"/>
</root>
</log4j:configuration>
When I create an errornous log4j.xml I also get an error from the SAXParser so it must be parsed. However I am still getting all DEBUG output. A second try was doing the following:
LiftRules.configureLogging = () => ()
Logger.setup = Full(Logback.withFile(getClass().getResource("/props/log4j.xml")))
Since I do not want to have Lift configure logging for me since the backend is already configured I would like to turn it completely off now. Oh and I also tried LogBoot.logSetup = () => false with no luck.
I would greatly appreciate any help on this issue.

The question got answered on the Lift mailing list.
The fix is to remove the logback dependency and to include both log4j and slf4j-log4j. No other configuration in boot() is required besides a valid default.log4j.xml.

I had a similar problem and came upon the following solution:
import net.liftweb.common.{ Empty, Logger }
import net.liftweb.http.Bootable
class BootLoader extends Bootable {
def boot = {
// other boot configuration ...
// prevent Lift from messing up my log4j config
Logger.setup = Empty
}
}

Related

Add a hook to Sentry Logback to scrub data

I'm using the Logback SDK for Java to send events to Sentry as described in the documentation.
Snippet:
<conversionRule conversionWord="CUSTOM_CONVERSION_RULE"
converterClass="clazz..." />
...
<property scope="context" name="myEnc" value="%d{ISO8601,UTC} | %-5level | %-50thread | %-55logger{55} | %CUSTOM_CONVERSION_RULE" />
...
<appender name="SENTRY" class="io.sentry.logback.SentryAppender">
<dsn>...</dsn>
<encoder>${myEnc}</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
....
The initial problem was that the events sent to Sentry were not converted by my custom conversion rule. All the other appenders such as Console that use the property myEnc containing the conversion rule parse the data as expected. But it seems that the io.sentry.logback.SentryAppender in combination with the encoder somehow doesn't do that. The filter property is working as well as the dsn one, so I get the errors in Sentry but not with my custom parsing.
The version that I use for io.sentry.sentry-logback (and transitively sentry) is 1.7.24.
I then read about before-send hook from Sentry docs which is what I want to control what data is sent to Sentry and I had to upgrade to latest for that which is 3.1.3 at the time of writing this.
The Logback XML config changed a bit:
<appender name="SENTRY" class="io.sentry.logback.SentryAppender">
<options>
<dsn>...</dsn>
<beforeSend>????</beforeSend>
</options>
...
</appender>
From what I can see the before-send hook is exactly what I need to scrub the data when required because I don't want some info to be sent to Sentry. docs
Now, the second issue is that I don't know how to ref here a method. In the Java config there is a BiFunction that takes the event and can alter it. But I want to apply this hook to all my log events, that's why the only place it is configured is in the Logback SDK.
In Spring Boot for example there is a starter for Sentry and, off course, a bean that you can inject in the auto-configuration.
But, I'm using Scala with no Spring Boot.
Also, the project is already in prod so I cannot change lots of things and I'm looking for the smallest one that will allow me to add a hook to Logback's SDK for Sentry.
Here is the appender and it looks like (I'm not sure how it works) the options can be populated from XML and than pass to init that will take all them into account, including my before send hook.
I don't know if it's accepted to have two questions and only one referenced in the title but I didn't find a nicer way to ask/explain the problem, because one thing lead to another.
To summarize the questions:
Why that custom rule is not working with Logback Sentry's appender.
How can I let the appender know about my hook and use it.
Thanks in advance!
You can configure Sentry independently from appender configuration in logback.xml. For example:
public class Main {
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
static {
Sentry.init(options -> {
options.setDsn("PUT YOUR DSN HERE");
options.setBeforeSend((sentryEvent, o) -> {
sentryEvent.setTag("custom", "tag");
return sentryEvent;
});
});
}
public static void main(String[] args) {
LOGGER.error("oops");
}
}
<configuration>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="sentry" class="io.sentry.logback.SentryAppender" />
<root level="debug">
<appender-ref ref="console"/>
<appender-ref ref="sentry"/>
</root>
</configuration>
Check complete code sample in github repo: https://github.com/maciej-scratches/sentry-logback-custom-config

Not create new log file once start my service with using log4j2

following is my configration of log4j2:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" name="MyApp" packages="com.swimap.base.launcher.log">
<Appenders>
<RollingFile name="RollingFile" fileName="logs/app-${date:MM-dd-yyyy-HH-mm-ss-SSS}.log"
filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="1 KB"/>
</Policies>
<DefaultRolloverStrategy max="3"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
the issue is that each time when start up my service, a new log will be created even the old one has not reached the specific size. If the program restart frequently, i will got many log files end with ‘.log’ which never be compressed.
the logs i got like this:
/log4j2/logs
/log4j2/logs/2017-07
/log4j2/logs/2017-07/app-07-18-2017-1.log.gz
/log4j2/logs/2017-07/app-07-18-2017-2.log.gz
/log4j2/logs/2017-07/app-07-18-2017-3.log.gz
/log4j2/logs/app-07-18-2017-20-42-06-173.log
/log4j2/logs/app-07-18-2017-20-42-12-284.log
/log4j2/logs/app-07-18-2017-20-42-16-797.log
/log4j2/logs/app-07-18-2017-20-42-21-269.log
someone can tell me how can i append log to the exists log file when i start up my program? much thanks whether u can help me closer to the answer!!
I suppose that your problem it that you have fileName="logs/app-${date:MM-dd-yyyy-HH-mm-ss-SSS}.log in your log4j2 configuration file.
This fileName template means that log4j2 will create log file with name that contains current date + hours + minutes + seconds + milliseconds in its name.
You should probably remove HH-mm-ss-SSS section and this will allow you to have daily rolling file and to not create new file every app restart.
You can play with template and choose format that you need.
If you want only one log file forever - then create constant fileName, like fileName=app.log
It's not hard to implement this. There is a interface DirectFileRolloverStrategy, implement below method:
public String getCurrentFileName(RollingFileManager manager)
Mybe someone met same problem and this can help him.

Logging in Identity Server 3

There seems to be a lot of people asking questions about this, and yet the folks over there have decided to close my question before it's resolved; the perception being that I'm a lazy developer and haven't read documentation - not the case: https://github.com/IdentityServer/IdentityServer3/issues/3083
I've followed the instructions here: https://identityserver.github.io/Documentation/docsv2/configuration/logging.html
but I cannot get logging to happen.
My question really at this point in time is, assuming I haven't done something wrong, does it matter that I'm firing things from a unit test method?
I have a separate unit test project which is just requesting a token and writing the response out, but I'm getting a 500 error somewhere and I'd assume logging would tell me why.
The test was working before I had some repo issues a while ago and lost some work, and I THINK I am back to where I was, but I'm sure the root cause will be something simple that I've overlooked - it usually is.
Anyway, I really hope someone can help, and not just be snotty.
Many thanks!
First adding logger to IdentityServer Configuration (if Owin, under Startup public void Configuration(IAppBuilder app) method;
Serilog.Log.Logger = new LoggerConfiguration()
.WriteTo.Trace(outputTemplate: "{Timestamp} [{Level}] ({Name}){NewLine} {Message}{NewLine}{Exception}")
.CreateLogger();
Then adding webconfig the following under configuration;
<system.diagnostics>
<sources>
<source name="Thinktecture.IdentityServer" switchValue="Information, ActivityTracing">
<listeners>
<add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="trace.svclog" />
</listeners>
</source>
</sources>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="sybsListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="Trace.log" />
<remove name="Default" />
</listeners>
</trace>
After running, and trying to interact with the IndentityServer, you can check the Trace.log file under your project. Don't forget selecting "Show All Files"
Based on Trace.log, can you specify the problem again if you can't solve?
I managed get logging working by wrapping my unit test in
using (var logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File(#"C:\Users\Richard Terris\Desktop\idsLogs.txt")
.CreateLogger())
{
It's not the best solution possibly, but it works!
Thanks for the replies!

log4j is not working with Jetty and liftweb app

I'm using a liftweb service over Jetty with log4j for logging.
here is how I setup the logger in Boot class:
val config = Properties.envOrElse("log4j.configuration","/props/syslog.log4j.xml")
val configFile = getClass.getResource(config)
Logger.setup = Full(Log4j.withFile(configFile))
When running the app as service (service jetty start), I can't see any log files written.
What am I doing wrong here?
This is my syslog.log4j.xml configuration file:
<root>
<level value="trace"/>
<appender-ref ref="CA"/>
<appender-ref ref="CA2"/>
</root>
Please read this wiki page to set up log4j:
https://www.assembla.com/spaces/liftweb/wiki/Logging

GWT: how to write client side logs into a log file in GWT

HI guys i am facing a big problem to write logs in a file in GWT.
i ahd gone through all the posts over internet but i didn't find any valuable information
there.
What i did ...
added remote logging servlet in web.xml file
inherited the logging module in my .gwt.xml file.
But my question is here now suppose i have written one log in my Entry Point class.
like ....
//Main class to start the appliation.....
public void onModuleLoad() {
Logger logger=Logger.getLogger(SYTMain.class.getName());
logger.info("Test Log in Module File");
}
and now i want to write this client side log into a test.log file .
How i can achieve this???/
Please if anyone knows the answer then plz provide me the complete solution, i don't want example on a fly. if you really know then only plz tell me don't give the answer which is already available in net.....
mY delivery date is very near so plz update on same ASAP, i'll be very thankful to you.
In your module file add the following:
<inherits name='com.google.gwt.logging.Logging'/>
<set-property name="gwt.logging.enabled" value="TRUE"/>
<!-- Set logging level to INFO -->
<set-property name="gwt.logging.logLevel" value="INFO"/>
<set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" />
<!-- Add compiler.stackMode to get a readable stacktrace from JavaScript
It generates a set of files in WEB-INF/deploy; those files need to
be placed on the server
-->
<set-property name="compiler.stackMode" value="emulated" />
In your web.xml add the following:
<servlet>
<servlet-name>remoteLoggingService</servlet-name>
<servlet-class>com.google.gwt.logging.server.RemoteLoggingServiceImpl</servlet-class>
</servlet>
<!-- Servlet Mapping -->
<servlet-mapping>
<servlet-name>remoteLoggingService</servlet-name>
<url-pattern>/<your module name>/remote_logging</url-pattern>
</servlet-mapping>
Replace <your module name> with as it says your module name.
To log simply use the code as your mentions. Use the import from java.util.logging.
On the client side, GWT compiles to Javascript, and Javascript cannot in general write files to the client's filesystem. (It should be obvious why this could be a bad idea). See for example this discussion.
If what you need is logs to use for debugging, one obvious solution is to have the logger append to a text area on the page. You can always copy and past manually into another file. Or, if you want to debug remotely, you could have the logger write to the server.
Just create a RPC service to log it into the server-side.
Use the servlet-side threadlocal to get info about the client: ThreadLocal to store ServletRequest and Response in servlet: what for?.