Usage of log4net to Always Log a Value - log4net

I have select few places in my application where I'd like to always log values. I could simply use Log.Info() and leave it at that, but I'd prefer a solution that can't be disabled by an accidental change to the level configuration. In this case, as long is log4net is not disabled, I want these log statements to fire.
What's the best approach?
Just looking at some information it looks like one option is to create a custom level with a value set above Emergency, but I don't know if that's a brutally awful hack with side effects I'm not realizing or a legitimate option. I couldn't find any clear guidance in the documentation.

I am not a log4net expert, but something like this might do what you want:
This code will get a named logger from the LogManager and will programmatically set its level to "ALL". If you retrieve this logger later in your code, it will always log, even if the log level is set to OFF in the config file.
To test, set the root log level to "OFF" in the config file, then use the code below:
log4net.ILog log = log4net.LogManager.GetLogger("abc");
log.Info("this won't log because root logger is OFF");
//Reset the level
log4net.Repository.Hierarchy.Logger l = (log4net.Repository.Hierarchy.Logger)log.Logger;
l.Level = l.Hierarchy.LevelMap["ALL"];
//Try to log again
log.Info("this will log because we just reset abc's level to ALL");
I tested it and it does seem to work.
I found this information here and here.

Related

MapUtils with Logger

I am using MapUtils.verbosePrint(System.out, "", map) to dump the contents of a map in Java. They (management) do not like us using System.out.println().
We are using log4j. They made the logger into a variable "l" so we can say something like l.debug("This is going to the logfile in debug mode).
I would like to get the output buffer(s) from l so I could pass it into verbosePrint() instead of System.out. I looked at all the methods and members of the logger and did things like getAppenders() and tried all those elements but I could not find anything that helped.
Has anyone else done this? I know the logger may write to > 1 output.
You can use Log4j IOStreams to create PrintStreams that will send everything to a logger. This is mostly useful to log debug output from legacy APIs like JDBC or Java Mail that do not have a proper logging system. I wouldn't advise it in other cases, since your messages might be merged or split into several log messages.
I would rather use one of these approaches:
simply log the map using Logger#debug(Object). This will lazily create an ObjectMessage (only if debug is enabled), which is usually formatted using the map's toString() method. Some layouts might format it differently (like the JSON Template Layout).
eagerly create a MapMessage or StringMapMessage:
if (l.isDebugEnabled()) {
l.debug(new MapMessage(map));
}
This gives you more formatting options. For example the layout pattern %m{JSON} will format your message as JSON.
if your are set on the format provided by MapUtils#verbosePrint, you can extend ObjectMessage and overwrite its getFormattedMessage() and formatTo() methods.
public String getFormattedMessage() {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
MapUtils.verbosePrint(new PrintStream(os), "", );
return new String(os.toByteArray());
}

How to use Spray's logRequestResponse in tests with debug level?

I am trying to follow this advice to debug my Spray routes, i.e. using logRequestResponse. I am using debug logging level. However, no debug messages appear on the console.
Firstly, the logRequestResponse directive takes an implicit LoggingContext parameter. LoggingContext will log to an implicit akka actor system if there is one in scope (see its Scaladoc for what it will do in other cases). There is an implicit actor system in scope in Spray Testkit, so if you are using that, that's probably the one that will be in scope. That loads from the standard locations (application.conf, reference.conf) so if you want to customise the config, you can do
override def testConfig = ...
Wherever you load the config from, it should contain at least
akka {
loglevel = "DEBUG"
}
to make debug logging show up.
Also, check the config file of your underlying slf4j logging implementation (e.g. log4j) to see where the log statements are being written and what are the minimum log levels in that config file, because that also affects the verbosity of the logging.

Log4j, dynamic file name based on .getLogger("") parameter

My application controls an arbitrary number of devices. I want to have log files for each of the devices. Basically, i want to be able to call LogManager.getLogger(deviceId) and log the corresponding thing.
I looked through a number of topics here and on other sites, still i am not quite sure if it is possible or not. I am not quite sure whether i should extend an appender or a logger.
How does one go about solving this task?
One solution, though it's not optimal, would be to add a fileappender in the constructor of your device object :
String device = "thing"
Logger log1 = Logger.getLogger("org.path."+device);
log1.setAdditivity(false);
log1.addAppender(new FileAppender(new SimpleLayout(), "org.path."+device ));

documentation on how to use MSBuild Namespace in C# Source code

I am looking for some simple answers on how to use funktionality from MSBuild in a c# program. The native documentation seems to be completely useless, because I only find information like:
ConsoleLogger.ApplyParameter
Applies a parameter to the logger
This is the prototype of a explanation, that had better never been written. Neither here, nor under the parameters type explanation you find e.g. a link or any examples about what the parameters might be there for, or their names, or where to find that information
The tutorials I find are all about MSBuild as a standalone tool.
At the moment I need to understand, how to get more information about a failed build:
This method just returns true or false.
bool success = project.Build(new string[] { "Build", "Deploy"}, fileLogger);
Also I need understand how to configure the filelogger, and how to use it from project.
Microsoft.Build.Logging.FileLogger fileLogger = new Microsoft.Build.Logging.FileLogger();
For the particular example in your question, ApplyParameter works the same way that the console logger parameters (/clp) work from the command line.
> msbuild /?
...
/consoleloggerparameters:<parameters>
Parameters to console logger. (Short form: /clp)
The available parameters are:
PerformanceSummary--Show time spent in tasks, targets
and projects.
Summary--Show error and warning summary at the end.
NoSummary--Don't show error and warning summary at the
end.
ErrorsOnly--Show only errors.
WarningsOnly--Show only warnings.
NoItemAndPropertyList--Don't show list of items and
properties at the start of each project build.
ShowCommandLine--Show TaskCommandLineEvent messages
ShowTimestamp--Display the Timestamp as a prefix to any
message.
ShowEventId--Show eventId for started events, finished
events, and messages
ForceNoAlign--Does not align the text to the size of
the console buffer
DisableConsoleColor--Use the default console colors
for all logging messages.
DisableMPLogging-- Disable the multiprocessor
logging style of output when running in
non-multiprocessor mode.
EnableMPLogging--Enable the multiprocessor logging
style even when running in non-multiprocessor
mode. This logging style is on by default.
Verbosity--overrides the /verbosity setting for this
logger.
Example:
/consoleloggerparameters:PerformanceSummary;NoSummary;
Verbosity=minimal
So for the example shown in the help,
logger.ApplyParameter("PerformanceSummary", "NoSummary");
logger.ApplyParameter("Verbosity", "minimal");
If you need a high degree of control over a logger you are attaching to the build engine from code, you might want to consider writing your own logger rather than trying to interpret/parse the text output from the stock console logger.

Using log4net as a logging mechanism for SSIS?

Does anyone know if it is possible to do logging in SSIS (SQL Server Integration Services) via log4net? If so, any pointers and pitfalls to be aware of? How's the deployment story?
I know the best solution to my problem is to not use SSIS. The reality is that as much as I hate this POS technology, the company I work with encourages the use of these apps instead of writing code. Meh.
So to answer my own question: it is possible. I'm not sure how our deployment story will be since this will be done in a few weeks from now.
I pretty much took the information from these sources and made it work. This one explains how to make referencing assemblies work with SSIS, click here. TLDR version: place it in the GAC and also copy the dll to the folder of your targetted framework. In my case, C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727. To programmatically configure log4net I ended up using this link as reference.
This is how my logger configuration code looks like for creating a file with the timestamp on it:
using log4net;
using log4net.Config;
using log4net.Layout;
using log4net.Appender;
public class whatever
{
private ILog logger;
public void InitLogger()
{
PatternLayout layout = new PatternLayout("%date [%level] - %message%newline");
FileAppender fileAppenderTrace = new FileAppender();
fileAppenderTrace.Layout = layout;
fileAppenderTrace.AppendToFile = false;
// Insert current date and time to file name
String dateTimeStr = DateTime.Now.ToString("yyyyddMM_hhmm");
fileAppenderTrace.File = string.Format("c:\\{0}{1}", dateTimeStr.Trim() ,".log");
// Configure filter to accept log messages of any level.
log4net.Filter.LevelMatchFilter traceFilter = new log4net.Filter.LevelMatchFilter();
traceFilter.LevelToMatch = log4net.Core.Level.All;
fileAppenderTrace.ClearFilters();
fileAppenderTrace.AddFilter(traceFilter);
fileAppenderTrace.ImmediateFlush = true;
fileAppenderTrace.ActivateOptions();
// Attach appender into hierarchy
log4net.Repository.Hierarchy.Logger root = ((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
root.AddAppender(fileAppenderTrace);
root.Repository.Configured = true;
logger = log4net.LogManager.GetLogger("root");
}
}
Hopefully this might help someone in the future or at least serve as a reference if I ever need to do this again.
Sorry, you didn't dig deep enough. There are 5 different destinations that you can log to, and 7 columns you can choose to include or not include in your logging as well as between 18 to 50 different events that you can capture logging on. You appear to have chosen the default logging, and dismissed it because it didn't work for you out of the box.
Check these two blogs for more information on what can be done with SSIS logging:
http://consultingblogs.emc.com/jamiethomson/archive/2005/06/11/SSIS_3A00_-Custom-Logging-Using-Event-Handlers.aspx
http://www.sqlservercentral.com/blogs/michael_coles/archive/2007/10/09/3012.aspx

Resources