how to configure log4net to work inside a CRM 2011 plugin? - log4net

I am trying to log some information inside a CRM 2011 plugin. I am not sure how to configure log4net. Where should I put log4net config file and how to reference from the plugin? Thanks!

Assuming you are registering your plugins to the database, you have a couple options:
Configure log4net programmatically. This can be done via the log4net API and could be driven by a configuration entity in crm.
Embed the log4net config file in the plugin assembly and configure log4net from a stream (shown below in a plugin base class that other plugins who wish to log could inherit from)
namespace TestPlugins
{
public abstract class BaseLoggingPlugin
{
protected static readonly ILog _log = LogManager.GetLogger(typeof(BaseLoggingPlugin));
static BaseLoggingPlugin()
{
using(var config = Assembly.GetExecutingAssembly().GetManifestResourceStream("TestPlugins.log4net.config"))
{
XmlConfigurator.Configure(config);
}
}
}
}

I want to add a warning to whatever the correct answer ends up being:
if you are registering your plugin assembly as a sandbox assembly (sandbox mode is required for CRM-online) you will not have access to the file system. In that case, your only option is Tracing. Good luck!

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?

Configure Eclipse for Log4j

I am working on an application using apache jena, to access dbpedia using sparql. Well I am very new to DBPedia and apache jena, I did some research and started with some sample code to create VCARD.
public class DpPedia extends Object {
static String personURI = "<!..http://def/JohnSmith..!>";
static String fullName = "John Smith";
static String Fullname = "Pulkit Gupta";
public static void main (String args[]) {
// create an empty model
Model model = ModelFactory.createDefaultModel();
// create the resource
Resource johnSmith = model.createResource(personURI);
Resource pulkitgupta=model.createResource(personABC);
// add the property
johnSmith.addProperty(VCARD.FN, fullName);
pulkitgupta.addProperty(VCARD.FN,Fullname);
}
}
However when i tried to execute this code .. It end up with an error
log4j:WARN No appenders could be found for logger (org.apache.jena.riot.stream.JenaIOEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
it seems my eclipse is not configured properly and I need to install Log4j. Well I downloaded the files, but not sure how up configure it with eclipse.
jena use log4j as logging system, and the warning messages tell explicitly that you are lacking of a log4j.properties to initialize it.
"This occurs when the default configuration files log4j.properties and log4j.xml can not be found and the application performs no explicit configuration."
Create log4j.properties file under src and retry. You can find some sample config files here
The easiest way to do this is by going to the folder where you extracted apache jena.
Find a properties file named : jena-log4j.properties. Copy this
Navigate to your workspace folder where you have your source project.
Go to bin folder and paste the file there. Make sure you rename the file to just log4j.properties
Clean the project and run it.
The errors would now have gone.
use org.apache.log4j.Logger.getRootLogger().setLevel(org.apache.log4j.Level.OFF);

Pluggable service assemblies. How to add list of assemblies without hardcoding tem in the AppHost constructor

I have question about how to make service assemblies pluggable (read them from config file) into the ServiceStack.
I want to register my services assemblies from configuration file and not to hard code them in the AppHost constructor like this:
public appHost() : base("My Pluggable Web Services", typeof(ServiceAssembly1).Assembly, typeof(AnotherServiceAssembly).Assembly) { }
I couldn't find other way to register the assemblies outside of this constructor. The constructor also accepts params and does not have overload for example with IEnumerable<Assembly> as parameter.
The idea is to be able to plug service assemblies without touching the service stack REST web site.
I looked at the Plugin interface but I think it is more suitable to be used to extend the service stack not to dynamically plug service assemblies.
Are there any way to implement such pluggable service assemblies feature with the current service stack release? Can you also add constructor overload that will accept the array of assembly?
Thank you in advance
The purpose of your ServiceStack's AppHost is to be a bespoke class customized for your solution that has hard references to all your service dependencies. It's much easier to verify your application is configured correctly, at build time if you declare your dependencies in code as opposed to un-typed configuration.
Having said that you can override the strategy that ServiceStack uses to discover your Service types by overriding AppHostBase.CreateServiceManager():
protected virtual ServiceManager CreateServiceManager(params Assembly[] assembliesWithServices)
{
return new ServiceManager(assembliesWithServices);
//Alternative way to inject Container + Service Resolver strategy
//return new ServiceManager(new Container(),
// new ServiceController(() => assembliesWithServices.ToList().SelectMany(x => x.GetTypes())));
}
Otherwise you can still do what you want by just passing your assemblies into your AppHost, e.g:
var appHost = new AppHost("Service Name", MyConfig.LoadAssembliesFromConfig());
(new AppHost()).Init();

Programmatically set Nhibernate to lower logging level for log4net

I have an application which logs to log4net but also uses Nhibernate. My app configures both Nhibernate (using Fluent Nhibernate config) and log4Net (using BasicConfigurator) programmatically .
Problem is my logs are full of Nhibernate log info which I don't need 99.9% of the time and the app slows down due to the full logging from Nhibernate.
How can I configure Nihbernate to not do any logging or log4Net to ignore all Nhibernate loggers programmatically? I know you can do it using xml config files but this is not an option for me.
Any help would be much appreciated.
See Log4Net: Programmatically specify multiple loggers (with multiple file appenders) where I stole this from:
public static void SetLevel(string loggerName, string levelName)
{
ILog log = LogManager.GetLogger(loggerName);
Logger l = (Logger)log.Logger;
l.Level = l.Hierarchy.LevelMap[levelName];
}
SetLevel("NHibernate","Error");

How to configure a default target in NLog

I am trying to convert existing logging library used by a bunch of apps to use NLog. The existing logging code has no indirection, logging calls go straight from the caller to a webservice call. The existing logging code is implemented as a static singleton. I need to do this in such a way that existing applications that use this library do not need configuration or code changes when they pick up the changed logging library. Later I can go update applications on an as needed basis, configuring a new logging target or changing the code to log to NLog directly.
To do this, I was going to make the static logging code go through NLog. Existing logging calls will be routed through NLog, and the existing webservice call will be wrapped in a custom NLog target.
To make this work on legacy apps without changing them, I need to programmatically set the custom target as the default (when none are configured in a config file). I'd like to do this without making config changes on the numerous existing applications, so I need to do this programmatically.
The problem is... its not working. Any thoughts on this approach? Below is the code I tried to add to hook in the existing logger class to create the default target.
I wouldn't mind going to log4net either. Just looking at the APIs I chose NLog initially as the names made more sense to me.
public static class LegacyLogger
{
static LegacyLogger()
{
if (LogManager.Configuration == null
|| LogManager.Configuration.GetConfiguredNamedTargets().Count == 0)
{
if (LogManager.Configuration == null)
{
LogManager.Configuration = new LoggingConfiguration();
}
//LogManager.Configuration.AddTarget("LegacyLogger", new NLog.Targets.DebuggerTarget());
LogManager.Configuration.AddTarget("LegacyLogger", new LegacyLoggerTarget());
}
_logger = LogManager.GetCurrentClassLogger();
}
Ok, if you're new to NLog, as I was, be advised the examples installed with the installer cover about everything. In this case, I needed:
public static class LegacyLogger
{
static LegacyLogger()
{
if (LogManager.Configuration == null
|| LogManager.Configuration.GetConfiguredNamedTargets().Count == 0)
{
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(new LegacyLoggerTarget(), LogLevel.Trace);
}
_logger = LogManager.GetCurrentClassLogger();
}

Resources