Logging from within WSO2 custom mediator - log4j

I want to be able to log from within a custom mediator that I have built.
A few questions:
What do I need to add to the esb's log4.properties to enable a custom class the ability to write to log files?
From within the custom mediator class, do I need declare the following to log to the synapse log file?
private static final Log log = LogFactory.getLog(<ClassName>.class);
I have seen many examples of using the log mediator, but I need to be able to control more of what I log from within mediator class.

By default your custom mediator logs will be sent to Carbon Log file as well as Carbon Memory and the console. And also you do not need to define
private static final Log log = LogFactory.getLog(.class);
again in your class, you can simply use the log object which is coming from AbstractMediator
Please refer the following guide which explains how to write your custom mediator as well as how you should log inside a mediator.
You can change the level of the log by editing the log4j.properties file or by going to configure -> logging using the management console to get more control on what to log and what not to log.

You can add the mediator class to log4j.properties
log4j.logger.org.foo.bar=ERROR, CARBON_LOGFILE, CARBON_MEMORY
Regards,
/Nuwan

Related

ServiceStack Log4NetFactory

How can I configure log4net in code when I like to use the servicestack logging interface? I see there is
LogManager.LogFactory = new Log4NetFactory(configureLog4Net:true);
If I got things right this expects a XML file containing the Log4Net configuration. I avoid XML config files whenever possible and usually configure Log4Net with my own static LoggerConfig class. There I setup all my appenders (EventLog, File, Console, etc.) using the Log4Net API.
Is there any way to integrate my class with the ServiceStack logging interface?

How do I configure Trace statements to go to the Portal in Windows Azure Mobile Services

I have a .Net back end mobile service and I would like my System.Diagnostics.Trace statements to go to the same destination as ApiServices.Log (i.e. the portal).
The reason for this is that I don't want to pass ITraceWriter down to my data tier due to the dependencies it adds (System.Web.Http etc).
I started to look at an approach where I would add to the trace listeners collection, similar to as described here:
http://blog.tylerdoerksen.com/2012/04/20/logging-in-azure-part-3-traceevent-logs/
But this adds an instance of DiagnosticMonitorTraceListener which doesn't exist by default in a MobileService as this lives in Microsoft.WindowsAzure.Diagnostics.
Does anyone know how to do this?
Thanks
F
In general, trace messages are written to the logs regardless of where they come from. For example, if I have a custom controller like this:
public string Get()
{
IHubContext hubContext = Services.GetRealtime<ChatHub>();
Trace.WriteLine("something!");
Trace.TraceError("error");
Trace.TraceInformation("info");
hubContext.Clients.All.hello("Hello Chat Hub clients from custom controller!");
return "Hello from custom controller!";
}
then "error" and "info" are written as you would expect. In fact, you can find the logs directly from within VS by using the Service Explorer and then Azure and Mobile Services. Right click on your service and select View Logs.
The only wrinkle is that verbose messages are not written as the default log level is Info. You can work around this by setting the level manually through the Kudu site:
https://.scm.azure-mobile.net
Then under the "Debug Console" drill down to Site/diagnostics and edit the file settings.json. It should look something like this:
"AzureDriveEnabled":true,"AzureDriveTraceLevel":"Information","AzureTableEnabled":false,"AzureTableTraceLevel":"Error","AzureBlobEnabled":false,"AzureBlobTraceLevel":"Error"}
Change the Information value to Verbose and you will get verbose messages as well.
Hope this helps!
Henrik

Extending log4net - Adding additional data to each log

We're working on logging in our applications, using log4net. We'd like to capture certain information automatically with every call. The code calling log.Info or log.Warn should call them normally, without specify this information.
I'm looking for a way to create something we can plug into log4net. Something between the ILog applications use to log and the appenders, so that we can put this information into the log message somehow. Either into ThreadContext, or the LogEventInfo.
The information we're looking to capture is asp.net related; the request url, user agent, etc. There's also some information from the apps .config file we want to include (an application id).
I want to get between the normal ILog.Info and appender so that this information is also automatically included for 3rd party libraries which also use log4net (Nhibernate, NServiceBus, etc).
Any suggestions on where the extensibility I want would be?
Thanks
What you are looking for is called log event context. This tutorial explains how it works:
http://www.beefycode.com/post/Log4Net-Tutorial-pt-6-Log-Event-Context.aspx
In particular the chapter 'Calculated Context Values' will interesting for you.
Update:
My idea was to use the global context. It is easy to see how this works for something like application ID (in fact there you do not even need a calculated context object). Dynamic information like request url could be done like this:
public class RequestUrlContext
{
public override string ToString()
{
string url;
// retrieve url from request
return url;
}
}
The object is global but the method is called on the thread that handles the request and thus you get the correct information. I also recommend that you create one class per "information entity" so that you have a lot of flexibility with the output in the log destination.

Can multiple log4j.properties files be used in the same Tomcat web app?

I'm writing a custom extension to an off-the-shelf Java web application. The application uses log4j for logging and I'd like to add a new logger and appender specifically for my extension. The problem is that the application manages the log4j.properties file which is dynamically generated based on selections in an admin screen UI. Since this is an "off-the-shelf" application, I can't modify the source code. So, if I add my own logger & appender(s) to the file, it gets overwritten anytime an admin changes logging preferences in the UI.
Is it possible to get log4j to get it's configuration from 2 files? For example, I'd want something like the following:
applog.properties #(Dynamically generated from admin UI)
mylog.properties #(My static properties)
In this scenario, log4j would somehow combine the entries from both files for the complete configuration.
Is this possible? or are there other workarounds?
I never did find a way to "merge" multiple log4j.properties file, but I did find a workable solution. log4j configuration can be manipulated programatically at runtime similar to the code snippet below. This effectively merged my custom log4j settings into the configuration defined by the log4j.properties file, which in my case I couldn't edit.
// Init custom logging
// Define layout
PatternLayout layout = new PatternLayout();
layout.setConversionPattern("%d [%-5p] -- %m%n");
// Create appender
RollingFileAppender appender = new RollingFileAppender();
appender.setFile(LOG_PATH);
appender.setMaxFileSize("2MB");
appender.setMaxBackupIndex(0);
appender.setLayout(layout);
appender.activateOptions(); // It didn't work without this
// Get our logger and add appender.
log = Logger.getLogger("[MyCustomLogger]");
log.setLevel(YOUR_LOGGING_LEVEL_HERE);
log.addAppender(appender);

Binsor and log4net

I'm using Castle Windsor and Binsor to use dependency injection in my application. I'm no expert at either one. Usually I can figure out how to bend Windsor to my will, but I find Binsor much harder, especially since I haven't found any decent documentation for it.
I'm trying to create a binsor configuration file where I use logging. I configure logging using the following binsor code:
facility LoggingFacility:
loggingApi = LoggerImplementation.Log4net
configFile = "ParasiteLogConf.log4net"
This works great, all components that are registered with the container and that takes an ILogger object as an argument to the constructor will receive the correct ILogger instance.
However, what I want to do now is to use another logger for one specific component. I want that component to log to a file, whereas the other components should only log to screen. How would I go about expressing that using Binsor code?
Aynede#Rahien is your friend here. He has many blog posts on using and configuring Binsor.
For the special logger, you need to add it as a component and then explicitly set the logger property of the dependent component to the id of the special logger component.

Resources