[Pkg-cli-libs-commits] [SCM] nlog branch, master, updated. ccb592cb9d6c3a88380f8247f6f3733104bac005
Mirco Bauer
meebey at meebey.net
Fri Mar 13 23:08:20 UTC 2009
The following commit has been merged in the master branch:
commit c9ee07af2c3f0be7ba5dd430c667749671b20868
Author: Mirco Bauer <meebey at meebey.net>
Date: Sat Mar 14 00:07:42 2009 +0100
Imported Upstream version 1.0+dfsg
diff --git a/AUTHORS.txt b/AUTHORS.txt
new file mode 100644
index 0000000..e019980
--- /dev/null
+++ b/AUTHORS.txt
@@ -0,0 +1,10 @@
+NLog is brought to you by:
+
+Jaroslaw Kowalski <jaak at jkowalski.net>
+Marcin Krupinski <yoszek at gmail.com>
+Inez Korczynski <korczynski at gmail.com>
+Rafal Gwizdala <gwrafal at poczta.onet.pl>
+Yuri Mamrukov <yvm at att.net>
+Maciej Figatowski <mfigatow at sav.net>
+Perry Rapp <lifelines_3_0_18 at hotmail.com>
+Maarten Claes <m.claes at farcourier.com>
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..3d2e62f
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,505 @@
+2006-09-18 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Preparing for 1.0 release
+
+2006-09-15 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Added MaxMessageSize (default: 65000) and OnOverflow (default:Split) to
+ the Network target
+
+2006-09-12 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Implemented headers and footers for the File target.
+ CAUTION: NLog automatically writes footers for files that have not been
+ written for 2 days (48 hours). This is done do conserve memory for
+ long-running processes that create lots of log files.
+
+2006-09-11 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Added publisher policy generation
+
+2006-09-07 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Enabled DatabaseTarget.ConnectionString to include
+ layouts.
+
+2006-09-04 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Build number is synchronized with SVN number (hopefully)
+ * Fixed LayoutRenderer.ApplyPadding() null handling
+ * First attempt at publisher policy generation
+
+2006-09-01 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Fixed File target for Windows 98
+
+2006-08-25 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Added examples of inheriting from Logger class and wrapping it
+
+2006-08-24 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Added infrastructure to create your own logger types inheriting from
+ Logger:
+
+ LogManager.GetLogger(string name, Type type) and
+ LogManager.GetCurrentClassLogger(Type type)
+ LogFactory.GetLogger(string name, Type type) and
+ LogFactory.GetCurrentClassLogger(Type type)
+
+ * Added ${event-context} layout renderer that extracts information from
+ LogEventInfo.Context
+ * Added eventID and categoryID parameters to EventLog targets.
+ * Added LogManager<LoggerType> that manages logger instances of LoggerType
+ where LoggerType : Logger
+ * Added missing code documentation
+ * Fixed Network target to work properly with IPV6
+ * Added example ${rot13} layout renderer - that demonstrates how
+ wrapper layout renderers can be written.
+ * Added support for DEFAULT nested layout parameters. You can now write:
+
+ ${file-contents:${basedir}/file.txt}
+ ${rot13:URYYB}
+
+2006-08-03 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * MANY CHANGES TO CLEAN UP APIs AND ENSURE EXTENSIBILITY - MAY TAKE SOME TIME TO STABILIZE AGAIN
+
+ * Added ${file-contents} layout renderer which inserts file contents.
+ * Added [DefaultParameter] attribute which allows for nameless parameters
+ to layout renderers:
+
+ ${aspnet-application}
+ ${aspnet-request}
+ ${aspnet-session}
+ ${date}
+ ${environment}
+ ${file-contents}
+ ${gdc}
+ ${mdc}
+ ${process-info}
+ ${special-folder}
+ ${asp-application}
+ ${asp-request}
+ ${asp-session}
+
+ * Added ILayoutWithHeaderAndFooter.cs for layouts that support
+ header/footer (such as CSV Layout, more to come)
+ * The following targets have been enhanced to support headers/footers:
+
+ Console
+ ColoredConsole
+ Debugger
+
+ * Added NLogConfigurationException which is thrown instead of CLR
+ exceptions when the configuration fails
+ * Simplified XmlLoggingConfiguration by splitting large methods and moving
+ common functionality to PropertyHelper
+ * Added Layouts/LayoutWithHeaderAndFooter.cs and
+ TargetWithLayoutHeaderAndFooter.cs
+ * Added MailTarget.AddNewLines to insert new lines between
+ header/lines/footer
+ * Added PopulateLayouts() method to ILayout
+ * BREAKING CHANGE: Changed the default value of
+ FileTarget.OpenFileCacheTimeout to -1
+ * Added support for nested layout renderers. Used in ${file-contents}
+
+ ${file-contents:fileName=${basedir}/aaa.txt}
+
+ This required a large rewrite of the parsing engine. Hopefully the test cases
+ cover all possible situations.
+ * Removed LogEventInfo.Empty and replaced with
+ LogEventInfo.CreateNullEvent()
+ * Added CsvLayout.WithHeader which can be used to disable CSV header.
+ * Added VJSharp and Web item templates. Updated the installer to support
+ VWD Express 2005.
+ * Enhanced XSD Schema generation by properly generating abstract and
+ layout properties.
+ * Some more unit tests.
+
+2006-07-31 Maarten Claes <m.claes at farcourier.com>
+ * Changed RichTextBox Target to be thread safe. Uses delegate to log
+ to RichTextBox
+ * Same changes made to FormControl Target
+
+2006-07-22 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Fixed NLogViewer and Chainsaw targets
+ * New NLog.Benchmark that uses code generation and compilation to
+ create more "clean" environment.
+ * Added ${gc} which can be used to get the GC statistics (very limited)
+ * Added ${processinfo} which can be used to extract the performance
+ information about the current process (possibly others in the future as
+ well)
+ * Added ${gc} which can be used to get the GC statistics (very limited)
+ * Added Initialize() and Close() to the LayoutRender class
+ * Added optimized CurrentTimeGetter which is way faster than DateTime.Now
+ * Some small optimizations
+
+2006-07-18 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Added ImpersonatingWrapper which temporarily changes the credentials
+ for the duration of the write.
+ * Moved the implementation of LogManager to a reusable LogFactory while
+ maintaining its public interface. You can now easily have a private
+ LogManager for an assembly.
+
+2006-07-17 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Synchronized Visual Studio solutions to source code directories. Now
+ part of the build process.
+
+2006-07-14 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Added proper camelCasing to the web build process
+ * Fix for multiple email addresses being passed in To,CC and BCC fields
+ under .NET 2.0 (reported by Pawel Parzychowski)
+
+2006-07-07 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * BREAKING CHANGE - Added NLog.ILayout which Layout implements to
+ allow other layout types (such as CSV-escaped, HTML-colored,
+ XML-escaped, ANSI-colored) to be implemented
+ NLog.Layout became sealed.
+ * BREAKING CHANGE - Added NLog.TargetWithLayout, removed Layout
+ and CompiledLayout from NLog.Target
+ * BREAKING CHANGE - Removed CSVFile target, converted examples to File + CsvLayout
+ * Added pluggable layouts (CSV, Log4JXml), LayoutFactory and
+ LayoutAttribute. The syntax is:
+
+ <target xsi:type="File">
+ <layout xsi:type="CSVLayout">
+ <column name="message" layout="${message}" />
+ <column name="level" layout="${level}" />
+ </layout>
+ </target>
+
+ Of course the old syntax is still supported for simple layouts:
+
+ <target xsi:type="File" layout="${message}" />
+ * BREAKING CHANGE - FileTarget.KeepFileOpen is back to the default
+ of false. Thankfully we now have <default-target-parameters /> so this
+ can be easily overriden.
+
+2006-07-05 Maciej Figatowski <mfigatow at sav.net>
+ * Added FilterResult.IgnoreFinal and FilterResult.LogFinal
+ which suppress processing of further rules if the filter
+ matches.
+
+2006-07-04 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Added NLog_Init() and NLog_InitLocal() APIs to NLogC
+
+2006-07-04 Marcin Krupinski <yoszek at gmail.com>
+ * added FormControl target that logs to Text property of any
+ Windows.Forms.Control
+ * added RichTextBox target with row- and word coloring that
+ logs to RichTextBox
+
+2006-06-30 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * added ${tempdir} and ${specialfolder}
+
+2006-06-29 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * implemented <targets><default-target-parametes /> </targets> that
+ specifies default values for all targets in the section
+
+2006-06-25 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * implemented <targets><default-wrapper /> </targets> that wraps all
+ targets in <targets> section with the specified wrapper.
+
+2006-06-23 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * fixed some race conditions in the Network target
+ * added NetworkTarget.Close()
+ * added CSVFile target which does proper CSV formatting (multi-line and
+ special character quoting)
+
+2006-06-14 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * added <include file="..." ignoreErrors="true|false" />
+ * fixed autoReload to keep monitoring the file if the reloaded file
+ has an error
+ * added Logger.Log(LogEventInfo) overload
+ * added Logger.Log(Type,LogEventInfo) overload
+ * added LoggerReconfiguredDelegate and Logger.LoggerReconfigured event
+
+2006-06-13 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Added BufferedWrapper.FlushTimeout
+ * Added some unit tests
+ * Fixed AsyncWrapper not closing files on termination.
+
+2006-06-11 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Added FileTarget.LineEnding
+ * Added some unit tests
+ * Added Layout.Escape() which escapes ${ with ${literal:text=${}
+
+2006-06-04 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Fixed compilation, schema generationa and website building on Linux/Mono.
+ * Updated version number to 1.0 (preparing for the release)
+ * Optimized file appenders
+ * added support for flags-type enumerations
+ * Benchmark updates
+ * Configurable stacktrace/separator
+
+2006-05-31 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Grammar issues (thanks Ron)
+ * Added "separator" option to the ${stacktrace} layout renderer.
+
+2006-05-30 Inez Korczynski <korczynski at gmail.com>
+ * Implementation of SOAP 1.2 and POST for WebService target.
+
+2006-05-28 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Preliminary implementation of SOAP 1.1 for WebService target.
+ * Added deleteOldFileOnStartup to the File target
+ * Added replaceFileContentsOnEachWrite to the File target
+ * We now have examples for 100% of targets, both
+ ready-to-run VS2005 projects and configuration files.
+
+2006-05-26 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Prepared ready-to-run example projects for VS2005 that describe
+ most targets.
+ * Added WebService target stub.
+
+2006-05-25 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Implemented AsyncWrapper for .NET CF using the Timer class
+ * Refactored file watching - should speed up non-logging by 100%
+
+2006-05-20 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Added support for VC#Express and VBExpress to the installer.
+ * Added VS2005 C# and VB.NET code snippet (nlogger) to quickly
+ insert logger creation statement
+ * Added VS2005 item templates for NLog configuration. Updated the
+ installer.
+ * Removed some stupid Console.Write()
+ * Updated MailTarget.SmtpAuthentication to be SmtpAuthenticationMode instead
+ of a string.
+
+
+2006-05-15 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Fixed File target causing delay at exit.
+ * Added generation of NLog.xsd schema for Intellisense.
+
+2006-05-15 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Reverted to NDoc 1.3.1 running under CLR 2.0 for docgen.
+
+2006-05-10 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * (hopefully) Fixed OpenFileCacheTimeout taking too much CPU
+
+2006-05-05 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Completely rebuilt the installer.
+ * Reworked the way documentation is generated. We now use NDoc 2.0 Alpha
+ 3k and there are still some minor issues.
+ * Separate compilation of NLog for all supported frameworks
+ * Cleaned up the code, now compiles with warnaserror="true"
+
+2006-04-22 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Merged NLog.Win32.dll, NLog.DotNet.dll, NLog.Unix.dll and NLog.Mono.dll
+ into one assembly NLog.dll
+ * Added attributes which mark support for particular runtimes and OSes
+
+2006-04-18 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Added LayoutRenderer.IsAppDomainFixed() and an optimization to turn
+ such things into literals.
+ * Added LoggingConfiguration.GetConfiguredNamedTargets() API
+ * BREAKING CHANGE - Completely restructured the way File target works.
+ The new structure is based on Streams instead of StreamWriters and
+ enables archiving (kind of similar to "rolling file appender" from log4net
+ world, but supporting multiple files at a time)
+ * BREAKING CHANGE - removed some properties which accepted strings. Now
+ replaced with enums.
+ * Added caching to File target to optimize the number file open/close
+ operations
+ * Added an option for multiple processes to append to the same OPEN file
+ in a synchronized manner. Unixes get this for free, but Win32 requires
+ you to use mutexes to synchronize file access.
+ * Enabled the use of enumerations as parameteters (including docgen)
+ * Added InternalLogger.LogToConsoleError and their config file and
+ environment variable counterparts
+ * Refactored website generation
+
+2006-03-27 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Updated .NET CF project file
+
+2006-03-21 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Fixed a programmatic configuration bug where invalid value was passed
+ to LoggingRule.LoggerNamePattern.
+ Thanks to danieljaysmith - at - excite - dot - com for spotting this.
+
+2006-03-19 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Optimization to defer calling String.Format() until it's really
+ needed.
+
+2006-02-24 Rafal Gwizdala <gwrafal at poczta.onet.pl>
+
+ * Add PerfCounter target that increases the PC value by one each
+ time the message is passed to it.
+ * Added FSNormalize option to ${identity} target to strip all
+ characters not allowed in the file names and replace them with
+ underscores.
+
+2006-02-24 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Added config-level option <targets async="true">...</targets>
+ to automatically wrap all targets with AsyncWrapper
+
+2006-02-14 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Updated license and email addresses.
+ * Updated assembly version and description for 0.95 release.
+
+2006-02-13 Yuri Mamrukov <yvm at att.net>
+
+ * Patch to simplify InternalLogger configuration from environment
+ variables and/or App.config settings. Fixes some nasty bug here.
+
+2006-02-13 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Added some docs, moving website to http://www.nlog-project.org/
+ * Excluded NLogViewer from build and project.
+ * Refactored LoggerImpl to allow for some extensibility in the future.
+
+2006-01-13 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Fixed a serious reentrancy bug which caused all sorts of problems
+ when formatted message included a parameter where ToString
+ did the logging itself.
+
+2005-10-26 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Added ${aspnet-sessionid} to access (guess!) ASP.NET session ID
+
+2005-10-25 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Added ASPNetBufferingWrapper target which buffers and post-processes
+ the entire ASP.NET request (requires you to use the NLogHttpModule)
+ * Added PostFilteringWrapper target which is able to filter log events
+ based on a buffer as a whole. It is possible for example to dump the
+ detailed ( >= Trace level) trace of a request if there was at least
+ one >= Warn event in the buffer, but under normal conditions only output
+ the >= Info levels.
+ * Reworked the way the documentation is generated (we no longer use
+ ugly IFRAMEs and the same method is used to generate the website and
+ the docs)
+ * Added a new conditions language (see conditions.html for more
+ information) which let you write powerful filtering conditions
+ while keeping the syntax natural and readable
+ * Added <when condition="..." action="..." /> filter which uses condition
+ expressions
+ * Added examples for the MailTarget and BufferedMailTarget
+ * Fixed Close() behaviour for unnamed targets (like the ones configured
+ by SimpleConfigurator)
+ * Added some more documentation (still some work to do before the release)
+ * Fixed the example for asynchronous Tile target (async="true" is not
+ supported and is replaced by the AsyncWrapper target)
+
+2005-10-21 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Added ${processname}, ${processid} layout renderers
+ * Added GDC (Global Diagnostics Context) and ${gdc} layout renderer which
+ is a global (as opposed to per-thread) version of MDC and ${mdc}
+
+2005-10-11 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Fixed a nullref exception when no config file was present.
+ * Fixed support for CC field in the Mail target
+
+2005-09-29 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Added batch NLogC compilation, added installer and nlogc binary
+ snapshot.
+ * Added authentication options to the Mail target (thanks Ron).
+
+2005-09-28 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+ * Refactored NLogViewer by separating NLogViewer.Interfaces
+ * Added NLogViewer.NDumbsterSmtpReceiver (by Ron Grabowski)
+ * Added support for caching layout results per logEvent which
+ makes them transportable across threads
+ * Renamed Target.Append() method to Write() (how did I forget it?)
+ * Added Target.Write(LogEvent[] manyEvents) for cases where the
+ target can optimize group writes
+ * Added Log4JXmlEvent.cs
+ * Added Wrappers: AsyncWrapper, AutoFlushWrapper, BufferingWrapper,
+ RepeatingWrapper, RetryingWrapper
+ * Some preliminary work on request buffering wrappers.
+ * Added compound targets (fallback, randomize, roundrobin, split)
+ * WARNING: This requires some serious testing.
+
+2005-09-19 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Added ${windows-identity} layout renderer. Restructured the
+ way extensions are loaded (ExtensionUtils).
+
+2005-08-28 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Some work on NLogViewer
+
+2005-08-14 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Fixed #34: Typos in the code prevented Chainsaw target
+ from working properly.
+ * Added #31: MSMQ target
+ * Added #30: EventLog target
+ * Fixed #8: Made Performance Counter layout renderer somewhat more
+ reliable and added a bit of documentation.
+ * Fixed #29: Root logging level support.
+ Added <nlog globalThreshold="..." />
+ * Massive website, documentation and packaging updates
+ * Added SimpleConfigurator.ConfigureForTargetLogging() and
+ SimpleConfigurator.ConfigureForFileLogging()
+
+2005-08-10 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Fixed #28: Documentation threading safety statement bug
+
+2005-08-08 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Added #27: Debugger target.
+ * Fixed #26: ${callsite} not working with database parameters
+
+2005-07-27 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Added #24: ${logger:shortname=true} option.
+
+2005-07-23 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Fixed #23: ${callsite} doesn't work with MethodCall target and
+ NLogViewer target
+
+2005-07-14 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * Fixed #22: Connection string builder omits ; after Server parameter
+
+2005-07-11 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * added an overridable FileTarget.WriteToFile method to allow for subclassing
+ of File target to support encryption
+
+2005-07-09 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * fixed the Trace target in Release mode by defining TRACE symbol
+
+2005-07-06 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * added a new Trace level, more verbose than the Debug
+
+2005-07-05 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * fixed VS.NET Compact Framework project file
+
+2005-06-28 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * added support for <variable name="" value="" /> configuration element
+ * added experimental PerformanceCounter layout renderer.
+
+2005-06-25 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * fixed the Trace target in Release mode by defining TRACE symbol
+
+2005-06-23 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * added some minimal VB.NET test code
+ * added some meaningful error message when a named target is not defined.
+
+2005-06-20 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * fixed bugs related to ${asp-request:cookie} and ${aspnet-request:cookie} and many other small bugs
+
+2005-06-17 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * fixes for case-insensitive parsing of the config files.
+ * added IgnoreCase option to filters
+ * added unit tests that verify case-insensitivity.
+ * added many more unit tests (we have now over 70% coverage)
+
+2005-06-16 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * fixed the filter configuration bug as reported by Ron Grabowski
+
+2005-06-10 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * added StackTrace layout renderer, 3 different logging formats
+ * added NewLine layout renderer
+ * added async="true" to the "File" target to improve logging speed by
+ writing messages in a separate thread and optimizing file access.
+ * fixed NLogC compilation
+ * refactored NLogViewer to use log4j schema instead of inventing my own
+ * fixed CompactFramework build
+
+2005-06-09 Jaroslaw Kowalski <jaak at jkowalski.net>
+ * NLog v0.9 has been released.
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..bd2fc0e
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,32 @@
+
+Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of Jaroslaw Kowalski nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/NLog.build b/NLog.build
new file mode 100644
index 0000000..47d5168
--- /dev/null
+++ b/NLog.build
@@ -0,0 +1,1373 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<project default="build" xmlns="http://nant.sf.net/NAnt.xsd">
+ <tstamp />
+
+ <tstamp property="buildtime" pattern="yyyy-MM-dd" verbose="true" />
+
+ <property name="nlog.debug" value="true" />
+ <property name="nlog.optimize" value="true" />
+ <property name="nlog.define" value="NANT" />
+
+ <property name="scp.program" value="pscp" />
+ <property name="ssh.program" value="plink" />
+ <property name="scp.args" value="-q -batch" />
+ <property name="ssh.args" value="-batch" />
+ <property name="benchmark.mode" value="short" />
+
+ <property name="deploy.host" value="jaak at sav.net" />
+
+ <property name="nlog.csc.args" value="/nowarn:1591" />
+ <property name="ndoc.version" value="2.0" />
+ <property name="sandcastle.dir" value="c:\program files\sandcastle" />
+ <property name="ndoc.basedir" value="D:\Apps\NDoc" unless="${property::exists('ndoc.basedir')}" />
+ <property name="ndoc.path" value="${ndoc.basedir}/${ndoc.version}" dynamic="true" />
+ <property name="ndoc.console.exe" value="${ndoc.path}/NDocConsole.exe" dynamic="true" />
+ <property name="ndoc.console.args" value="-referencepath "${framework::get-assembly-directory(framework::get-target-framework())}"" dynamic="true" />
+ <property name="prettyprinter.exe" value="tools/PrettyPrinter.exe" />
+ <property name="ndocsyntax.path" value="tools/NDocSyntax.exe" />
+ <property name="benchmark.loop.unroll" value="4" />
+
+ <property name="webserver.deploy.dir" value="web/www.nlog-project.org/html" />
+ <property name="csc.warninglevel" value="4" />
+
+ <property name="nlog.package.name" value="${tstamp.date}" unless="${property::exists('nlog.package.name')}" />
+ <property name="nlog.release.dir" value="releases/${nlog.package.name}" />
+ <property name="ilmerge.version" value="1" />
+ <property name="log4net.bin.dir" value="../log4net-1.2.10/bin" />
+ <property name="enterpriselib.bin.dir" value="C:\Program Files\Microsoft Enterprise Library January 2006\bin" />
+
+ <property name="installer.name" value="${nlog.release.dir}/nlog-${nlog.package.name}-setup.exe" />
+ <property name="installer.debug.name" value="${nlog.release.dir}/nlog-${nlog.package.name}-setup-debug.exe" />
+ <property name="source_snapshot.name" value="${nlog.release.dir}/nlog-${nlog.package.name}-src.zip" />
+ <property name="binary_snapshot.name" value="${nlog.release.dir}/nlog-${nlog.package.name}-${framework::get-target-framework()}${if(nlog.debug,'-debug','')}.zip" dynamic="true" />
+ <property name="help_package.name" value="${nlog.release.dir}/nlog-${nlog.package.name}-help.zip" />
+ <property name="webtest.dir" value="${project::get-base-directory()}/webtest" />
+
+ <property name="clover.enabled" value="false" />
+ <property name="clover.home" value="D:\Apps\CloverNLog" />
+
+ <target name="detectversion">
+ </target>
+
+ <target name="configure">
+ <call target="configure-${framework::get-target-framework()}" />
+ <property name="buildsubdir" value="${framework::get-target-framework()}${if(clover.enabled,'-clover','')}${if(nlog.debug,'-debug','')}" />
+ <property name="nlog.dir" value="${project::get-base-directory()}/build/${buildsubdir}/bin" unless="${property::exists('nlog.dir')}" />
+ <property name="nlog.help.dir" value="build/${buildsubdir}/help" unless="${property::exists('nlog.help.dir')}" />
+ <property name="nunit2.report.dir" value="${project::get-base-directory()}/build/${buildsubdir}/test_results" />
+ <property name="clover.report.dir" value="build/${buildsubdir}/clover_report" />
+ <property name="clover.build.dir" value="build/${buildsubdir}/clover" />
+
+ <echo message="Building NLog for ${framework::get-target-framework()}" />
+ <echo message="Package name: ${nlog.package.name}" />
+ <echo message="Target dir: ${nlog.dir}" />
+
+ <mkdir dir="${nlog.dir}" />
+ <mkdir dir="${nlog.release.dir}" />
+ </target>
+
+ <target name="build" depends="configure, build-${framework::get-target-framework()}">
+ </target>
+
+ <target name="debug">
+ <property name="nlog.debug" value="true" />
+ <property name="nlog.optimize" value="false" />
+ </target>
+
+ <target name="release">
+ <property name="nlog.debug" value="false" />
+ <property name="nlog.optimize" value="true" />
+ </target>
+
+ <target name="binary_snapshot" depends="build">
+ <zip zipfile="${binary_snapshot.name}">
+ <fileset basedir="build/${buildsubdir}">
+ <include name="bin/*" />
+ </fileset>
+ <fileset basedir=".">
+ <include name="LICENSE.txt" />
+ <include name="examples/**/*" />
+ </fileset>
+ <fileset basedir="src/NLogC">
+ <include name="NLogC FAQ.txt" />
+ </fileset>
+ </zip>
+ </target>
+
+ <target name="clean" depends="configure">
+ <delete dir="build/${buildsubdir}" failonerror="false" />
+ <delete verbose="true">
+ <fileset basedir=".">
+ <include name="**/*.suo" />
+ <include name="**/*.ncb" />
+ </fileset>
+ </delete>
+ <delete verbose="true">
+ <fileset basedir="src">
+ <include name="*/bin/**" />
+ <include name="*/obj/**" />
+ <include name="*/bin" />
+ <include name="*/obj" />
+ <include name="NLogC/Debug/**" />
+ <include name="NLogC/Release/**" />
+ <include name="NLogC/Debug" />
+ <include name="NLogC/Release" />
+ </fileset>
+ </delete>
+ <delete verbose="true">
+ <fileset basedir="tools">
+ <include name="*/bin/**" />
+ <include name="*/obj/**" />
+ <include name="*/bin" />
+ <include name="*/obj" />
+ </fileset>
+ </delete>
+ <delete verbose="true">
+ <fileset basedir="tests">
+ <include name="*/bin/**" />
+ <include name="*/obj/**" />
+ <include name="*/bin" />
+ <include name="*/obj" />
+ <include name="NLogCTest/Debug/**" />
+ <include name="NLogCTest/Release/**" />
+ <include name="NLogCTest/Debug" />
+ <include name="NLogCTest/Release" />
+ </fileset>
+ </delete>
+ </target>
+
+ <target name="update-build-number">
+ <exec program="tools/UpdateBuildNumber.exe" commandline="NLog.version src/NLog/AssemblyBuildInfo.cs build/NLog.buildversion" useruntimeengine="true" />
+ <exec program="tools/UpdateBuildNumber.exe" commandline="NLog.version src/NLog.ComInterop/AssemblyBuildInfo.cs build/NLog.buildversion" useruntimeengine="true" />
+ <foreach item="Line" in="build/NLog.buildversion" delim="." property="tmp1,tmp2,tmp3,tmp4">
+ <property name="nlog.version.major" value="${tmp1}" />
+ <property name="nlog.version.minor" value="${tmp2}" />
+ <property name="nlog.version.revision" value="${tmp3}" />
+ <property name="nlog.version.build" value="${tmp4}" />
+ </foreach>
+
+ <property name="nlog.version" value="${nlog.version.major}.${nlog.version.minor}.${nlog.version.revision}.${nlog.version.build}" />
+ </target>
+
+ <target name="NLog" depends="configure, update-build-number">
+ <csc target="library" output="${nlog.dir}/NLog.dll" doc="${nlog.dir}/NLog.xml" define="${nlog.define}" debug="${nlog.debug}" optimize="${nlog.optimize}" warninglevel="${csc.warninglevel}" warnaserror="true">
+ <sources basedir="src">
+ <include name="NLog/**/*.cs" />
+ </sources>
+ <references>
+ <include name="mscorlib.dll" />
+ <include name="System.dll" />
+ <include name="System.Xml.dll" />
+ <include name="System.Data.dll" />
+ <include name="System.Configuration.dll" />
+ <include name="System.Messaging.dll" />
+ <include name="System.Windows.Forms.dll" />
+ <include name="System.Web.dll" />
+ <include name="System.Web.Services.dll" />
+ <include name="Mono.Posix.dll" />
+ </references>
+ <arg value="${nlog.csc.args}"/>
+ </csc>
+ </target>
+
+ <target name="xmldoc" depends="configure">
+ <mkdir dir="build/doc" />
+
+ <property name="oldframework" value="${nant.settings.currentframework}" />
+
+ <property name="nant.settings.currentframework" value="mono-2.0" failonerror="false" />
+ <property name="nant.settings.currentframework" value="net-2.0" failonerror="false" />
+
+ <csc target="library" output="build/doc/NLog.dll" doc="build/doc/NLog.xml" warninglevel="0" define="DOCUMENTATION;NANT">
+ <sources basedir="src">
+ <include name="NLog/**/*.cs" />
+ </sources>
+ <references>
+ <include name="mscorlib.dll" />
+ <include name="System.dll" />
+ <include name="System.Xml.dll" />
+ <include name="System.Data.dll" />
+ <include name="System.Messaging.dll" />
+ <include name="System.Windows.Forms.dll" />
+ <include name="System.Web.dll" />
+ <include name="System.Web.Services.dll" />
+ <include name="Mono.Posix.dll" />
+ </references>
+ </csc>
+
+ <exec program="${ndocsyntax.path}"
+ commandline="build/doc/NLog.xml"
+ workingdir="." useruntimeengine="true" />
+ <uptodate property="xmldoc.uptodate">
+ <targetfiles>
+ <include name="build/doc/doc.xml" />
+ </targetfiles>
+ <sourcefiles basedir="build/doc">
+ <include name="**/*.dll" />
+ </sourcefiles>
+ </uptodate>
+ <if test="${not xmldoc.uptodate}">
+ <exec program="${ndoc.console.exe}"
+ verbose="true" workingdir="."
+ commandline="${ndoc.console.args} -documenter=XML -project=./NLog.ndoc"
+ useruntimeengine="true" />
+ <exec program="${ndocsyntax.path}"
+ commandline="build/doc/doc.xml"
+ workingdir="." useruntimeengine="true" />
+ </if>
+ <echo message="Getting target, filter and layout renderer names from build/doc/doc.xml ..." />
+ <script language="C#">
+ <code><![CDATA[
+ public static void ScriptMain(Project project) {
+ System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
+ doc.Load(project.ExpandProperties("${project::get-base-directory()}/build/doc/doc.xml", Location.UnknownLocation));
+ string targets = "";
+ string layoutRenderers = "";
+ string filters = "";
+ string layouts = "";
+
+ // NDoc 2.0 XML layout
+ foreach (System.Xml.XmlNode node in doc.SelectNodes("//attribute[@id='T:NLog.TargetAttribute']/argument[position()=1]/@value"))
+ {
+ if (targets != "")
+ targets += ",";
+ targets += node.InnerText;
+ }
+ foreach (System.Xml.XmlNode node in doc.SelectNodes("//attribute[@id='T:NLog.LayoutRendererAttribute']/argument[position()=1]/@value"))
+ {
+ if (layoutRenderers != "")
+ layoutRenderers += ",";
+ layoutRenderers += node.InnerText;
+ }
+ foreach (System.Xml.XmlNode node in doc.SelectNodes("//attribute[@id='T:NLog.FilterAttribute']/argument[position()=1]/@value"))
+ {
+ if (filters != "")
+ filters += ",";
+ filters += node.InnerText;
+ }
+
+ foreach (System.Xml.XmlNode node in doc.SelectNodes("//attribute[@id='T:NLog.LayoutAttribute']/argument[position()=1]/@value"))
+ {
+ if (layouts != "")
+ layouts += ",";
+ layouts += node.InnerText;
+ }
+
+ // NDoc 1.1 XML layout
+ foreach (System.Xml.XmlNode node in doc.SelectNodes("//attribute[@name='NLog.TargetAttribute']/property[@name='Name']/@value"))
+ {
+ if (targets != "")
+ targets += ",";
+ targets += node.InnerText;
+ }
+ foreach (System.Xml.XmlNode node in doc.SelectNodes("//attribute[@name='NLog.LayoutRendererAttribute']/property[@name='FormatString']/@value"))
+ {
+ if (layoutRenderers != "")
+ layoutRenderers += ",";
+ layoutRenderers += node.InnerText;
+ }
+ foreach (System.Xml.XmlNode node in doc.SelectNodes("//attribute[@name='NLog.FilterAttribute']/property[@name='Name']/@value"))
+ {
+ if (filters != "")
+ filters += ",";
+ filters += node.InnerText;
+ }
+ foreach (System.Xml.XmlNode node in doc.SelectNodes("//attribute[@name='NLog.LayoutAttribute']/property[@name='Name']/@value"))
+ {
+ if (layouts != "")
+ layouts += ",";
+ layouts += node.InnerText;
+ }
+
+ project.Properties["nlog.targetNames"] = targets;
+ project.Properties["nlog.layoutRendererNames"] = layoutRenderers;
+ project.Properties["nlog.filterNames"] = filters;
+ project.Properties["nlog.layoutNames"] = layouts;
+
+ }
+ ]]></code>
+ </script>
+ <echo message="Target names: ${nlog.targetNames}" />
+ <echo message="Layout renderer names: ${nlog.layoutRendererNames}" />
+ <echo message="Filter names: ${nlog.filterNames}" />
+ <property name="nant.settings.currentframework" value="${oldframework}" />
+ </target>
+
+ <target name="NLog.ComInterop" depends="NLog">
+ <csc target="library" output="${nlog.dir}/NLog.ComInterop.dll" doc="${nlog.dir}/NLog.ComInterop.xml" define="${nlog.define}" debug="${nlog.debug}" optimize="${nlog.optimize}" warninglevel="${csc.warninglevel}">
+ <sources basedir="src/NLog.ComInterop">
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${nlog.dir}/NLog.dll" />
+ <include name="mscorlib.dll" />
+ <include name="System.dll" />
+ <include name="System.Xml.dll" />
+ </references>
+ <arg value="${nlog.csc.args}"/>
+ </csc>
+ </target>
+
+ <target name="NLog.UnitTests" depends="NLog">
+ <copy file="${nant::get-base-directory()}/lib/${framework::get-family(framework::get-target-framework())}/${framework::get-version(framework::get-target-framework())}/nunit.framework.dll" tofile="${nlog.dir}/nunit.framework.dll" />
+ <csc target="library" output="${nlog.dir}/NLog.UnitTests.dll" define="${nlog.define}" debug="${nlog.debug}" optimize="${nlog.optimize}" warninglevel="${csc.warninglevel}">
+ <sources basedir="tests/NLog.UnitTests">
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${nlog.dir}/NLog.dll" />
+ <include name="${nlog.dir}/nunit.framework.dll" />
+ </references>
+ </csc>
+ <csc target="exe" output="${nlog.dir}/Runner.exe" define="${nlog.define}" debug="${nlog.debug}" optimize="${nlog.optimize}" warninglevel="${csc.warninglevel}">
+ <sources basedir="tools">
+ <include name="Runner.cs" />
+ </sources>
+ </csc>
+ </target>
+
+ <target name="NLog.UnitTests.Web" depends="NLog">
+ <copy file="${nant::get-base-directory()}/lib/${framework::get-family(framework::get-target-framework())}/${framework::get-version(framework::get-target-framework())}/nunit.framework.dll" tofile="${nlog.dir}/nunit.framework.dll" />
+ <csc target="library" output="${nlog.dir}/NLog.UnitTests.Web.dll" define="${nlog.define}" debug="${nlog.debug}" optimize="${nlog.optimize}" warninglevel="${csc.warninglevel}">
+ <sources basedir="tests/NLog.UnitTests.Web">
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${nlog.dir}/NLog.dll" />
+ <include name="${nlog.dir}/nunit.framework.dll" />
+ </references>
+ </csc>
+ </target>
+
+ <target name="NLog.Test" depends="NLog">
+ <csc target="exe" output="${nlog.dir}/NLog.Test.exe" define="${nlog.define}" debug="${nlog.debug}" optimize="${nlog.optimize}" warninglevel="${csc.warninglevel}">
+ <sources basedir="tests/NLog.Test">
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${nlog.dir}/NLog.dll" />
+ <include name="mscorlib.dll" />
+ <include name="System.dll" />
+ <include name="System.Xml.dll" />
+ </references>
+ </csc>
+ <copy file="tests/NLog.Test/App.config" tofile="${nlog.dir}/NLog.Test.exe.config" />
+ </target>
+
+ <target name="NLog.Benchmark" depends="NLog">
+ <csc target="exe" output="${nlog.dir}/NLog.Benchmark.exe" define="${nlog.define};NLOG" debug="${nlog.debug}" optimize="${nlog.optimize}" warninglevel="${csc.warninglevel}">
+ <sources basedir="tests/NLog.Benchmark">
+ <include name="*.cs" />
+ </sources>
+ <references>
+ <include name="${nlog.dir}/NLog.dll" />
+ <include name="mscorlib.dll" />
+ <include name="System.dll" />
+ <include name="System.Xml.dll" />
+ </references>
+ </csc>
+ <copy todir="${nlog.dir}">
+ <fileset basedir="tests/NLog.Benchmark">
+ <include name="NLog.config" />
+ <include name="*.png" />
+ <include name="*.xsl" />
+ </fileset>
+ </copy>
+ <property name="log4netbinary" value="${log4net.bin.dir}/${framework::get-family(framework::get-target-framework())}/${framework::get-version(framework::get-target-framework())}/${if(nlog.debug,'debug','release')}/log4net.dll" />
+ <if test="${file::exists(log4netbinary)}">
+ <copy file="${log4netbinary}" tofile="${nlog.dir}/log4net.dll" />
+ <copy file="tests/NLog.Benchmark/log4net.config" tofile="${nlog.dir}/log4net.config" />
+ </if>
+ <exec program="${nlog.dir}/NLog.Benchmark.exe" workingdir="${nlog.dir}" commandline="Benchmark.xml ${benchmark.mode}" useruntimeengine="true" />
+ </target>
+
+ <target name="NLog.Benchmark-LAB" depends="NLog">
+ <copy todir="${nlog.dir}">
+ <fileset basedir="${enterpriselib.bin.dir}">
+ <include name="Microsoft.Practices.*.dll" />
+ <include name="Microsoft.Practices.*.pdb" />
+ </fileset>
+ </copy>
+ <delete file="${nlog.dir}/NLog.Benchmark-log4net.exe" failonerror="false" />
+ <exec program="perl" commandline="tests/NLog.Benchmark/unroll_loop.pl tests/NLog.Benchmark/Benchmark.cs tests/NLog.Benchmark/Benchmark.Unrolled.cs ${benchmark.loop.unroll}" />
+ <csc target="exe" output="${nlog.dir}/NLog.Benchmark-lab.exe" define="${nlog.define},ENTLIB" debug="${nlog.debug}" optimize="${nlog.optimize}" warninglevel="${csc.warninglevel}">
+ <sources basedir="tests/NLog.Benchmark">
+ <include name="**/*.cs" />
+ <exclude name="Benchmark.cs" />
+ </sources>
+ <references>
+ <include name="mscorlib.dll" />
+ <include name="System.dll" />
+ <include name="System.Xml.dll" />
+ <include name="${nlog.dir}/Microsoft.*.dll" />
+ </references>
+ </csc>
+ <copy file="tests/NLog.Benchmark/EntLibLAB.config" tofile="${nlog.dir}/NLog.Benchmark-lab.exe.config" />
+ <exec program="${nlog.dir}/NLog.Benchmark-lab.exe" workingdir="${nlog.dir}" commandline="Benchmark-lab.xml ${benchmark.mode}" />
+ </target>
+
+ <target name="pfiles">
+ <property name="nlog.dir" value="${environment::get-folder-path('ProgramFiles')}\NLog\bin\${framework::get-target-framework()}" unless="${property::exists('nlog.dir')}" />
+ </target>
+
+ <target name="NLogC" depends="NLog, NLogC-${framework::get-target-framework()}">
+ <copy todir="${nlog.dir}/include">
+ <fileset basedir="tests/NLogC">
+ <include name="NLogC.h" />
+ <include name="NLogger.h" />
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="NLogC-compile">
+ <path id="build.path.include">
+ <pathelement dir="${visualc.dir}/INCLUDE" />
+ </path>
+
+ <path id="build.path.lib">
+ <pathelement dir="${visualc.dir}/LIB" />
+ <pathelement dir="${path::combine(framework::get-sdk-directory(framework::get-target-framework()),'..')}/LIB" />
+ </path>
+
+ <path id="build.path">
+ <pathelement dir="${visualstudio.dir}/Common7/IDE" />
+ <pathelement dir="${visualc.dir}/BIN" />
+ </path>
+
+ <setenv verbose="true">
+ <variable name="INCLUDE">
+ <path refid="build.path.include" />
+ </variable>
+ <variable name="LIB">
+ <path refid="build.path.lib" />
+ </variable>
+ <variable name="PATH">
+ <path refid="build.path" />
+ </variable>
+ </setenv>
+
+ <delete dir="${nlog.dir}/obj" if="${directory::exists(nlog.dir + '/obj')}" />
+ <mkdir dir="${nlog.dir}/obj" />
+
+ <cl outputdir="${nlog.dir}/obj" options='/D "_CRT_SECURE_NO_DEPRECATE" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "NLOGC_EXPORTS" /D "_WINDLL" /D "_MBCS" /FD /GS /W3 /c /Wp64 /Zi /TP ${nlogc.compile.extraoptions}'>
+ <sources basedir="src/NLogC">
+ <include name="**/*.cpp" />
+ </sources>
+ <forcedusingfiles>
+ <include name="${framework::get-framework-directory(framework::get-target-framework())}/mscorlib.dll" />
+ <include name="${nlog.dir}/NLog.dll" />
+ </forcedusingfiles>
+ </cl>
+ <link output="${nlog.dir}/NLogC.dll"
+ pdbfile="${nlog.dir}/NLogC.pdb"
+ options="/nologo /INCREMENTAL:NO /NOLOGO /DLL /DEBUG /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /MACHINE:X86 /FIXED:No /NOENTRY /NODEFAULTLIB:nochkclr.obj /INCLUDE:__DllMainCRTStartup at 12">
+ <sources basedir="${nlog.dir}/obj">
+ <include name="*.obj" />
+ </sources>
+ </link>
+ <delete dir="${nlog.dir}/obj" />
+ </target>
+
+ <target name="NLogC-net-1.0">
+ <readregistry property="visualstudio.dir" key="SOFTWARE\Microsoft\VisualStudio\7.0\Setup\VS\ProductDir" />
+ <readregistry property="visualc.dir" key="SOFTWARE\Microsoft\VisualStudio\7.0\Setup\VC\ProductDir" failonerror="false" />
+ <if test="${not property::exists('visualc.dir')}">
+ <property name="visualc.dir" value="${visualstudio.dir}\VC7" />
+ </if>
+ <property name="nlogc.compile.extraoptions" value="/clr" />
+ <call target="NLogC-compile" />
+ </target>
+
+ <target name="NLogC-net-1.1">
+ <readregistry property="visualstudio.dir" key="SOFTWARE\Microsoft\VisualStudio\7.1\Setup\VS\ProductDir" />
+ <readregistry property="visualc.dir" key="SOFTWARE\Microsoft\VisualStudio\7.1\Setup\VC\ProductDir" failonerror="false" />
+ <if test="${not property::exists('visualc.dir')}">
+ <property name="visualc.dir" value="${visualstudio.dir}\VC7" />
+ </if>
+ <property name="nlogc.compile.extraoptions" value="/clr" />
+ <call target="NLogC-compile" />
+ </target>
+
+ <target name="NLogC-net-2.0" depends="configure">
+ <readregistry property="visualstudio.dir" key="SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS\ProductDir" />
+ <readregistry property="visualc.dir" key="SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VC\ProductDir" failonerror="false" />
+ <if test="${not property::exists('visualc.dir')}">
+ <property name="visualc.dir" value="${visualstudio.dir}\VC" />
+ </if>
+ <property name="nlogc.compile.extraoptions" value="/clr:oldsyntax" />
+ <call target="NLogC-compile" />
+ </target>
+
+ <!-- unsupported platforms -->
+ <target name="NLogC-mono-1.0" />
+ <target name="NLogC-mono-2.0" />
+ <target name="NLogC-netcf-1.0" />
+ <target name="NLogC-netcf-2.0" />
+
+ <target name="NLog.Benchmark-log4net" depends="NLog">
+ <copy file="${log4net.bin.dir}/${framework::get-family(framework::get-target-framework())}/${framework::get-version(framework::get-target-framework())}/${if(nlog.debug,'debug','release')}/log4net.dll" tofile="${nlog.dir}/log4net.dll" />
+ <delete file="${nlog.dir}/NLog.Benchmark-log4net.exe" failonerror="false" />
+ <csc target="exe" output="${nlog.dir}/NLog.Benchmark-log4net.exe" define="${nlog.define},LOG4NET" debug="${nlog.debug}" optimize="${nlog.optimize}" warninglevel="${csc.warninglevel}">
+ <sources basedir="tests/NLog.Benchmark">
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${nlog.dir}/log4net.dll" />
+ <include name="mscorlib.dll" />
+ <include name="System.dll" />
+ <include name="System.Xml.dll" />
+ </references>
+ </csc>
+ <copy file="tests/NLog.Benchmark/log4net.config" tofile="${nlog.dir}/log4net.config" />
+ <exec program="${nlog.dir}/NLog.Benchmark-log4net.exe" workingdir="${nlog.dir}" commandline="Benchmark-log4net.xml ${benchmark.mode}" />
+ </target>
+
+ <target name="NLog.Benchmark-log4net-withformat" depends="NLog">
+ <copy file="${log4net.bin.dir}/${framework::get-family(framework::get-target-framework())}/${framework::get-version(framework::get-target-framework())}/${if(nlog.debug,'debug','release')}/log4net.dll" tofile="${nlog.dir}/log4net.dll" />
+ <delete file="${nlog.dir}/NLog.Benchmark-log4net.exe" failonerror="false" />
+ <exec program="perl" commandline="tests/NLog.Benchmark/unroll_loop.pl tests/NLog.Benchmark/Benchmark.cs tests/NLog.Benchmark/Benchmark.Unrolled.cs ${benchmark.loop.unroll}" />
+ <csc target="exe" output="${nlog.dir}/NLog.Benchmark-log4net.exe" define="${nlog.define},LOG4NET,LOG4NETWITHFORMAT" debug="${nlog.debug}" optimize="${nlog.optimize}" warninglevel="${csc.warninglevel}">
+ <sources basedir="tests/NLog.Benchmark">
+ <include name="**/*.cs" />
+ <exclude name="Benchmark.cs" />
+ </sources>
+ <references>
+ <include name="${nlog.dir}/log4net.dll" />
+ <include name="mscorlib.dll" />
+ <include name="System.dll" />
+ <include name="System.Xml.dll" />
+ </references>
+ </csc>
+ <copy file="tests/NLog.Benchmark/log4net.config" tofile="${nlog.dir}/log4net.config" />
+ <exec program="${nlog.dir}/NLog.Benchmark-log4net.exe" workingdir="${nlog.dir}" commandline="Benchmark-log4net-withformat.xml ${benchmark.mode}" />
+ </target>
+
+ <target name="NLog.Benchmark-log4net-with-concrete-logger" depends="NLog">
+ <copy file="${log4net.bin.dir}/${framework::get-family(framework::get-target-framework())}/${framework::get-version(framework::get-target-framework())}/${if(nlog.debug,'debug','release')}/log4net.dll" tofile="${nlog.dir}/log4net.dll" />
+ <delete file="${nlog.dir}/NLog.Benchmark-log4net.exe" failonerror="false" />
+ <csc target="exe" output="${nlog.dir}/NLog.Benchmark-log4net.exe" define="${nlog.define},LOG4NET_WITH_FASTLOGGER" debug="${nlog.debug}" optimize="${nlog.optimize}" warninglevel="${csc.warninglevel}">
+ <sources basedir="tests/NLog.Benchmark">
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${nlog.dir}/log4net.dll" />
+ <include name="mscorlib.dll" />
+ <include name="System.dll" />
+ <include name="System.Xml.dll" />
+ </references>
+ </csc>
+ <copy file="tests/NLog.Benchmark/log4net.config" tofile="${nlog.dir}/log4net.config" />
+ <exec program="${nlog.dir}/NLog.Benchmark-log4net.exe" workingdir="${nlog.dir}" commandline="Benchmark-log4net-concrete-logger.xml ${benchmark.mode}" />
+ </target>
+
+ <target name="all-benchmarks" depends="NLog.Benchmark, NLog.Benchmark-log4net-withformat" />
+
+ <target name="test" depends="NLog.UnitTests">
+ <if test="${framework::get-family(framework::get-target-framework())=='net'}">
+ <nunit2 failonerror="false">
+ <formatter type="Xml" usefile="true" extension=".xml" outputdir="build/${buildsubdir}/test_results_xml" />
+ <test assemblyname="${nlog.dir}/NLog.UnitTests.dll" />
+ </nunit2>
+ </if>
+
+ <if test="${framework::get-family(framework::get-target-framework())=='mono'}">
+ <mkdir dir="build/${buildsubdir}/test_results_xml" />
+ <exec workingdir="${nlog.dir}" program="nunit-console" verbose="true"
+ commandline="NLog.UnitTests.dll /labels /xml=${project::get-base-directory()}/build/${buildsubdir}/test_results_xml/NLog.UnitTests.dll-results.xml" />
+ </if>
+ </target>
+
+ <target name="webtest" depends="NLog, NLog.ComInterop, NLog.UnitTests.Web">
+ <!-- stop IIS on local machine -->
+
+ <echo message="Stopping IIS..." />
+ <exec program="iisreset.exe" commandline="/stop" />
+
+ <!-- copy binaries to the "bin" directory -->
+
+ <copy todir="${webtest.dir}/bin" verbose="true">
+ <fileset basedir="${nlog.dir}">
+ <include name="NLog.dll" />
+ <include name="NLog.ComInterop.dll" />
+ <include name="cloverruntime.dll" />
+ </fileset>
+ </copy>
+
+ <!-- register NLog.ComInterop.dll COM component -->
+
+ <echo message="Registering COM interop library..." />
+
+ <exec program="${path::combine(framework::get-framework-directory(framework::get-target-framework()),'regasm.exe')}"
+ commandline="/tlb /codebase ${webtest.dir}/bin/NLog.ComInterop.dll" />
+
+ <!-- start IIS -->
+
+ <echo message="Starting IIS..." />
+ <exec program="iisreset.exe" commandline="/start" />
+
+ <sleep seconds="5" />
+
+ <!-- run unit tests -->
+
+ <echo message="Running tests..." />
+
+ <nunit2 failonerror="false">
+ <formatter type="Xml" usefile="true" extension=".xml" outputdir="build/${buildsubdir}/test_results_xml" />
+ <test assemblyname="${nlog.dir}/NLog.UnitTests.Web.dll" />
+ </nunit2>
+
+ <sleep seconds="5" />
+
+ <echo message="Running tests again..." />
+
+ <nunit2 failonerror="false">
+ <formatter type="Xml" usefile="true" extension=".xml" outputdir="build/${buildsubdir}/test_results_xml" />
+ <test assemblyname="${nlog.dir}/NLog.UnitTests.Web.dll" />
+ </nunit2>
+
+ <if test="false">
+
+ <sleep seconds="5" /> <!-- give Clover some time to dump its statistics -->
+
+ <!-- stop IIS -->
+
+ <echo message="Stopping IIS..." />
+ <exec program="iisreset.exe" commandline="/stop" />
+
+ <!-- unregister COM components -->
+
+ <echo message="Unregistering COM interop library..." />
+
+ <exec program="${path::combine(framework::get-framework-directory(framework::get-target-framework()),'regasm.exe')}"
+ commandline="/unregister /tlb ${webtest.dir}/bin/NLog.ComInterop.dll" if="false" />
+
+ <!-- start IIS -->
+ <echo message="Starting IIS..." />
+ <exec program="iisreset.exe" commandline="/start" />
+ </if>
+
+ </target>
+
+ <target name="dowebtest" depends="NLog, NLog.ComInterop, NLog.UnitTests.Web">
+ <echo message="Running tests..." />
+
+ <nunit2 failonerror="false">
+ <formatter type="Xml" usefile="true" extension=".xml" outputdir="build/${buildsubdir}/test_results_xml" />
+ <test assemblyname="${nlog.dir}/NLog.UnitTests.Web.dll" />
+ </nunit2>
+ </target>
+
+ <target name="configure-mono-1.0">
+ <property name="nlog.define" value="${nlog.define};MONO;MONO_1_0" />
+ </target>
+ <target name="configure-mono-2.0">
+ <property name="nlog.define" value="${nlog.define};MONO;MONO_2_0;NET_2_API" />
+ <property name="nlog.csc.args" value="/nowarn:1591,1699" />
+ </target>
+
+ <target name="configure-net-1.0">
+ <property name="nlog.define" value="${nlog.define};DOTNET;DOTNET_1_0" />
+ </target>
+
+ <target name="configure-net-1.1">
+ <property name="nlog.define" value="${nlog.define};DOTNET;DOTNET_1_1" />
+ <property name="ilmerge.version" value="1.1" />
+ </target>
+
+ <target name="configure-net-2.0">
+ <property name="ilmerge.version" value="2" />
+ <property name="nlog.define" value="${nlog.define};DOTNET;DOTNET2;DOTNET_2_0;NET_2_API" />
+ <property name="nlog.csc.args" value="/nowarn:1591,1699" />
+ </target>
+
+ <target name="configure-netcf-1.0">
+ <property name="nlog.define" value="${nlog.define};NETCF;NETCF_1_0" />
+ </target>
+
+ <target name="configure-netcf-2.0">
+ <property name="nlog.define" value="${nlog.define};NETCF;NETCF_2_0;NET_2_API" />
+ <property name="nlog.csc.args" value="/nowarn:1591,1699" />
+ </target>
+
+ <target name="build-mono-1.0" depends="NLog, publisher-policy" />
+ <target name="build-mono-2.0" depends="NLog, publisher-policy" />
+ <target name="build-net-1.0" depends="NLog, NLog.ComInterop, NLogC, publisher-policy" />
+ <target name="build-net-1.1" depends="NLog, NLog.ComInterop, NLogC, publisher-policy" />
+ <target name="build-net-2.0" depends="NLog, NLog.ComInterop, NLogC, publisher-policy" />
+ <target name="build-netcf-1.0" depends="NLog" />
+ <target name="build-netcf-2.0" depends="NLog" />
+
+ <target name="publisher-policy" depends="configure, update-build-number">
+ <uptodate property="publisherpolicy.uptodate">
+ <targetfiles>
+ <include name="${nlog.dir}/Policy.${nlog.version.major}.${nlog.version.minor}.NLog.dll" />
+ </targetfiles>
+ <sourcefiles basedir=".">
+ <include name="src/NLog/AssemblyBuildInfo.cs" />
+ </sourcefiles>
+ </uptodate>
+ <if test="${not publisherpolicy.uptodate}">
+ <copy file="src/publisher_policy.config.template" tofile="${nlog.dir}/Policy.${nlog.version.major}.${nlog.version.minor}.NLog.xml" />
+ <xmlpoke file="${nlog.dir}/Policy.${nlog.version.major}.${nlog.version.minor}.NLog.xml" xpath="/configuration/runtime/ms:assemblyBinding/ms:dependentAssembly/ms:bindingRedirect/@oldVersion"
+ value="${nlog.version.major}.${nlog.version.minor}.0.0-${nlog.version.major}.${nlog.version.minor}.${nlog.version.revision}.${int::parse(nlog.version.build) - 1}">
+ <namespaces>
+ <namespace prefix="ms" uri="urn:schemas-microsoft-com:asm.v1" />
+ </namespaces>
+ </xmlpoke>
+ <xmlpoke file="${nlog.dir}/Policy.${nlog.version.major}.${nlog.version.minor}.NLog.xml" xpath="/configuration/runtime/ms:assemblyBinding/ms:dependentAssembly/ms:bindingRedirect/@newVersion"
+ value="${nlog.version.major}.${nlog.version.minor}.${nlog.version.revision}.${nlog.version.build}">
+ <namespaces>
+ <namespace prefix="ms" uri="urn:schemas-microsoft-com:asm.v1" />
+ </namespaces>
+ </xmlpoke>
+
+ <exec program="${path::combine(framework::get-framework-directory(framework::get-target-framework()),'al')}"
+ commandline="/nologo /link:Policy.${nlog.version.major}.${nlog.version.minor}.NLog.xml /out:Policy.${nlog.version.major}.${nlog.version.minor}.NLog.dll /keyfile:${path::combine(project::get-base-directory(),'src/NLog.snk')} /version:1.0.0.0"
+ workingdir="${nlog.dir}" />
+ </if>
+ </target>
+
+ <target name="installer" depends="allframeworksdebugandrelease, clean_examples, help, vs2005templates">
+ <readregistry property="nsis.dir" key="SOFTWARE\NSIS\" />
+ <property name="makensis.exe" value="${nsis.dir}/makensis.exe" />
+
+ <exec program="${makensis.exe}" commandline="/DNLOGVERSION=${nlog.package.name} /DOPTIONALDEBUG= tools\SetupNLog.nsi" verbose="true" />
+ <move file="SetupNLog.exe" tofile="${installer.name}" overwrite="true" />
+ <exec program="${makensis.exe}" commandline="/DNLOGVERSION=${nlog.package.name}-debug /DOPTIONALDEBUG=-debug tools\SetupNLog.nsi" verbose="true" />
+ <move file="SetupNLog.exe" tofile="${installer.debug.name}" overwrite="true" />
+ </target>
+
+ <target name="allframeworksdebugandrelease">
+ <call target="debug" />
+ <call target="allframeworks" />
+ <call target="release" />
+ <call target="allframeworks" />
+ </target>
+
+ <target name="allframeworks">
+ <property name="debugrelease" value="release" />
+ <property name="debugrelease" value="debug" if="${nlog.debug}" />
+ <exec program="nant" commandline="-t:net-1.0 -D:nlog.package.name=${nlog.package.name} ${debugrelease} build schema binary_snapshot" />
+ <exec program="nant" commandline="-t:net-1.1 -D:nlog.package.name=${nlog.package.name} ${debugrelease} build schema binary_snapshot" />
+ <exec program="nant" commandline="-t:net-2.0 -D:nlog.package.name=${nlog.package.name} ${debugrelease} build schema binary_snapshot" />
+ <exec program="nant" commandline="-t:netcf-1.0 -D:nlog.package.name=${nlog.package.name} ${debugrelease} build binary_snapshot" />
+ <exec program="nant" commandline="-t:netcf-2.0 -D:nlog.package.name=${nlog.package.name} ${debugrelease} build binary_snapshot" />
+ <exec program="nant" commandline="-t:mono-1.0 -D:nlog.package.name=${nlog.package.name} ${debugrelease} build schema binary_snapshot" />
+ <exec program="nant" commandline="-t:mono-2.0 -D:nlog.package.name=${nlog.package.name} ${debugrelease} build schema binary_snapshot" />
+ </target>
+
+ <target name="sandcastle-help" depends="xmldoc,helpwebsite">
+ <mkdir dir="build/doc/sandcastle" />
+ <copy file="build/doc/NLog.xml" tofile="build/doc/sandcastle/comments.xml" />
+ <copy file="${sandcastle.dir}/Presentation/Configuration/Sandcastle.config" tofile="build/doc/sandcastle/Sandcastle.config">
+ <filterchain>
+ <replacestring from=""..\..\" to=""${sandcastle.dir}\" />
+ <replacestring from=""..\" to=""${sandcastle.dir}\Examples\" />
+ </filterchain>
+ </copy>
+ <exec program="${sandcastle.dir}/ProductionTools/MRefBuilder.exe" commandline="../NLog.dll /out:reflection.xml" workingdir="build/doc/sandcastle" />
+ <exec program="${sandcastle.dir}/ProductionTools/XslTransform.exe"
+ commandline=""${sandcastle.dir}/ProductionTransforms/AddOverloads.xsl" reflection.xml /out:reflection2.xml"
+ workingdir="build/doc/sandcastle" />
+ <exec program="${sandcastle.dir}/ProductionTools/XslTransform.exe"
+ commandline=""${sandcastle.dir}/ProductionTransforms/AddGuidFileNames.xsl" reflection2.xml /out:reflection.xml"
+ workingdir="build/doc/sandcastle" />
+ <exec program="${sandcastle.dir}/ProductionTools/XslTransform.exe"
+ commandline=""${sandcastle.dir}/ProductionTransforms/ReflectionToManifest.xsl" reflection.xml /out:manifest.xml"
+ workingdir="build/doc/sandcastle" />
+ <mkdir dir="build/doc/sandcastle/Output" />
+ <mkdir dir="build/doc/sandcastle/Output/html" />
+ <copy todir="build/doc/sandcastle/Output">
+ <fileset basedir="${sandcastle.dir}/Presentation">
+ <include name="art/*" />
+ <include name="scripts/*" />
+ <include name="styles/*" />
+ </fileset>
+ </copy>
+ <copy todir="build/doc/sandcastle/Output/html">
+ <fileset basedir="build/doc/helpweb">
+ <include name="**/*" />
+ </fileset>
+ </copy>
+ <exec program="${sandcastle.dir}/ProductionTools/BuildAssembler.exe"
+ commandline="manifest.xml /config:Sandcastle.config"
+ workingdir="build/doc/sandcastle" />
+ <exec program="${sandcastle.dir}/ProductionTools/XslTransform.exe"
+ commandline=""${sandcastle.dir}/ProductionTransforms/ReflectionToChmContents.xsl" reflection.xml /arg:html=Output\html /out:Output\test.hhc"
+ workingdir="build/doc/sandcastle" />
+ <copy file="NLog.hhp" tofile="build/doc/sandcastle/Output/NLog.hhp" />
+ <exec program="C:\Program Files\HTML Help Workshop\hhc.exe" commandline="NLog.hhp" workingdir="build/doc/sandcastle/Output" />
+ </target>
+
+ <target name="help" depends="xmldoc, helpwebsite">
+ <copy file="${project::get-base-directory()}/web/syntax.xsl" tofile="build/doc/syntax.xsl" overwrite="true" />
+ <xmlpoke file="build/doc/syntax.xsl" xpath="//xsl:param[@name='external-base']" value="file://${webbuild.dir}">
+ <namespaces>
+ <namespace prefix="xsl" uri="http://www.w3.org/1999/XSL/Transform" />
+ </namespaces>
+ </xmlpoke>
+ <copy todir="build/doc/help/examples">
+ <fileset basedir="build/doc/helpweb/examples">
+ <include name="**/*" />
+ </fileset>
+ </copy>
+ <uptodate property="help.uptodate">
+ <targetfiles>
+ <include name="${help_package.name}" />
+ </targetfiles>
+ <sourcefiles basedir=".">
+ <include name="build/doc/NLog.dll" />
+ <include name="build/doc/helpweb/**/*" />
+ <include name="NLog-${ndoc.version}.ndoc" />
+ </sourcefiles>
+ </uptodate>
+ <if test="${not help.uptodate}">
+ <exec program="${ndoc.console.exe}" verbose="true" workingdir="." commandline="${ndoc.console.args} -documenter=MSDN -project=.\NLog.ndoc" />
+ <zip zipfile="${help_package.name}">
+ <fileset basedir="build/doc/help">
+ <include name="NLog.chm" />
+ </fileset>
+ </zip>
+ </if>
+ </target>
+
+ <target name="cleanwebsite" depends="xmldoc, website">
+ </target>
+
+ <target name="publish_website_help" depends="help">
+ <zip zipfile="web.zip">
+ <fileset basedir="build/doc/help">
+ <include name="**/*" />
+ <exclude name="**/NLog.chm" />
+ </fileset>
+ </zip>
+ <echo message="Uploading web.zip and tools/web_install.sh to ${deploy.host}..." />
+ <exec program="${scp.program}" commandline="${scp.args} web.zip tools/web_install.sh ${deploy.host}:." workingdir="." />
+ <echo message="Spawning web_install.sh..." />
+ <exec program="${ssh.program}" commandline="${ssh.args} ${deploy.host} dos2unix web_install.sh && /bin/bash web_install.sh ${webserver.deploy.dir}/help" workingdir="." />
+ </target>
+
+ <target name="publish_clover" depends="clover">
+ <zip zipfile="web.zip">
+ <fileset basedir="${clover.report.dir}">
+ <include name="**/*" />
+ </fileset>
+ </zip>
+ <echo message="Uploading web.zip and tools/web_install.sh to ${deploy.host}..." />
+ <exec program="${scp.program}" commandline="${scp.args} web.zip tools/web_install.sh ${deploy.host}:." workingdir="." />
+ <echo message="Spawning web_install.sh..." />
+ <exec program="${ssh.program}" commandline="${ssh.args} ${deploy.host} dos2unix web_install.sh && /bin/bash web_install.sh ${webserver.deploy.dir}/clover" workingdir="." />
+ <echo message="Coverage results deployed." />
+ </target>
+
+ <target name="source_snapshot" depends="update-build-number">
+ <delete dir="build/source_snapshot" if="${directory::exists('build/source_snapshot')}" />
+ <property name="snapshot.dir" value="build/source_snapshot/NLog-${nlog.package.name}" />
+ <mkdir dir="build/source_snapshot" if="${not directory::exists('build/source_snapshot')}" />
+ <exec program="svn" commandline="export . ${snapshot.dir}" />
+ <copy file="build/NLog.buildversion" tofile="${snapshot.dir}/NLog.version" />
+ <copy todir="${snapshot.dir}">
+ <fileset basedir=".">
+ <include name="src/**/AssemblyBuildInfo.cs" />
+ </fileset>
+ </copy>
+ <zip zipfile="${source_snapshot.name}">
+ <fileset basedir="build/source_snapshot">
+ <include name="**/*" />
+ <exclude name="_svn" />
+ </fileset>
+ </zip>
+ </target>
+
+ <target name="astyle">
+ <astyle style="NAnt" cleanup="true" >
+ <fileset>
+ <include name="**/*.cs" />
+ <exclude name="**/_*.cs" />
+ </fileset>
+ </astyle>
+ </target>
+
+ <target name="sln">
+ <call target="clean" />
+
+
+ <property name="oldframework" value="${nant.settings.currentframework}" />
+
+ <property name="nant.settings.currentframework" value="net-1.1" failonerror="false" />
+
+ <solution configuration="Release" solutionfile="NLog.vs2003.sln" />
+ <solution configuration="Debug" solutionfile="NLog.vs2003.sln" />
+ <solution configuration="Release" solutionfile="tests/NLogTests.vs2003.sln" />
+ <solution configuration="Debug" solutionfile="tests/NLogTests.vs2003.sln" />
+ <property name="nant.settings.currentframework" value="${oldframework}" failonerror="false" />
+
+ <call target="clean" />
+
+ <exec program="${framework::get-framework-directory('net-2.0')}/msbuild.exe" commandline="/p:Configuration=Debug /t:Rebuild NLog.vs2005.sln" />
+ <exec program="${framework::get-framework-directory('net-2.0')}/msbuild.exe" commandline="/p:Configuration=Release /t:Rebuild NLog.vs2005.sln" />
+ <exec program="${framework::get-framework-directory('net-2.0')}/msbuild.exe" commandline="/p:Configuration=Debug /t:Rebuild tests\NLogTests.vs2005.sln" />
+ <exec program="${framework::get-framework-directory('net-2.0')}/msbuild.exe" commandline="/p:Configuration=Release /t:Rebuild tests\NLogTests.vs2005.sln" />
+
+ <call target="clean" />
+ </target>
+
+ <target name="upload_web_snapshot">
+ <property name="webserver.deploy.dir" value="${webserver.deploy.dir}/snapshots/${nlog.package.name}/web" />
+ <call target="deploy-web" />
+ </target>
+
+ <target name="schema" depends="NLog, xmldoc">
+ <uptodate property="schema.uptodate">
+ <targetfiles>
+ <include name="${nlog.dir}/NLog.xsd" />
+ </targetfiles>
+ <sourcefiles>
+ <include name="${nlog.dir}/NLog.dll" />
+ <include name="build/doc/doc.xml" />
+ <include name="tools/MakeNLogXSD/TemplateNLog.xsd" />
+ <include name="tools/MakeNLogXSD/Program.cs" />
+ </sourcefiles>
+ </uptodate>
+ <if test="${not schema.uptodate}">
+ <csc target="exe" output="${nlog.dir}/MakeNLogXSD.exe" define="${nlog.define}" warninglevel="${csc.warninglevel}" failonerror="false">
+ <sources>
+ <include name="tools/MakeNLogXSD/Program.cs" />
+ </sources>
+ <references>
+ <include name="${nlog.dir}/NLog.dll" />
+ <include name="mscorlib.dll" />
+ <include name="System.dll" />
+ <include name="System.Xml.dll" />
+ </references>
+ <resources basedir="tools/MakeNLogXSD" prefix="MakeNLogXSD" dynamicprefix="true">
+ <include name="TemplateNLog.xsd" />
+ </resources>
+ </csc>
+ <exec program="${nlog.dir}/MakeNLogXSD.exe"
+ commandline="NLog.xsd "${project::get-base-directory()}/build/doc/doc.xml""
+ workingdir="${nlog.dir}" useruntimeengine="true" />
+ <delete file="${nlog.dir}/MakeNLogXSD.exe" />
+ </if>
+ </target>
+
+ <target name="vs2005templates">
+ <mkdir dir="build/templates" />
+ <foreach item="String" in="Empty,Typical,Console" delim="," property="projecttype">
+ <foreach item="String" in="CSharp,VisualBasic,JSharp" delim="," property="language">
+ <!-- standard version -->
+ <delete dir="tmp_dir" failonerror="false" />
+ <copy todir="tmp_dir">
+ <fileset basedir="tools/VS2005Templates/ItemTemplates/${projecttype}NLogConfig">
+ <include name="**/*" />
+ </fileset>
+ <filterchain>
+ <replacestring from="$nlogversion$" to="${nlog.version}" />
+ <replacestring from="$projecttype$" to="${language}" />
+ <replacestring from="$projectsubtype$" to="" />
+ </filterchain>
+ </copy>
+ <zip zipfile="build/templates/${language}${projecttype}NLogConfig.zip">
+ <fileset basedir="tmp_dir">
+ <include name="**/*" />
+ </fileset>
+ </zip>
+
+ <!-- web standard version -->
+ <delete dir="tmp_dir" failonerror="false" />
+ <copy todir="tmp_dir">
+ <fileset basedir="tools/VS2005Templates/ItemTemplates/${projecttype}NLogConfig">
+ <include name="**/*" />
+ </fileset>
+ <filterchain>
+ <replacestring from="$nlogversion$" to="${nlog.version}" />
+ <replacestring from="$projecttype$" to="Web" />
+ <replacestring from="$projectsubtype$" to="${language}" />
+ </filterchain>
+ </copy>
+ <zip zipfile="build/templates/Web${language}${projecttype}NLogConfig.zip">
+ <fileset basedir="tmp_dir">
+ <include name="**/*" />
+ </fileset>
+ </zip>
+ </foreach>
+ </foreach>
+ <delete dir="tmp_dir" failonerror="false" />
+ </target>
+
+ <target name="install-schema-vs2005" depends="schema">
+ <readregistry property="visualstudio.dir" key="SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS\ProductDir" />
+ <copy file="${nlog.dir}/NLog.xsd" tofile="${visualstudio.dir}/Xml/Schemas/NLog.xsd" />
+ </target>
+
+ <target name="upload_snapshot">
+ <echo message="Creating a directory for ${nlog.package.name}..." />
+ <exec program="${ssh.program}" commandline="${ssh.args} ${deploy.host} mkdir -p ${webserver.deploy.dir}/snapshots/${nlog.package.name} ${webserver.deploy.dir}/snapshots/${nlog.package.name}/web" failonerror="false" />
+ <echo message="Uploading nlog-${nlog.package.name}*.*..." />
+ <exec program="${scp.program}" commandline="${scp.args} ${nlog.release.dir}/nlog-${nlog.package.name}*.* ${deploy.host}:${webserver.deploy.dir}/snapshots/${nlog.package.name}/" />
+ <echo message="Uploading ChangeLog..." />
+ <exec program="${scp.program}" commandline="${scp.args} ChangeLog ${deploy.host}:${webserver.deploy.dir}/snapshots/${nlog.package.name}/" />
+ <echo message="Uploading NLog.buildversion..." />
+ <exec program="${scp.program}" commandline="${scp.args} build/NLog.buildversion ${deploy.host}:${webserver.deploy.dir}/snapshots/${nlog.package.name}/" />
+ <echo message="Calculating MD5SUM..." />
+ <exec program="${ssh.program}" commandline="${ssh.args} ${deploy.host} (cd ${webserver.deploy.dir}/snapshots/${nlog.package.name}; md5sum nlog-${nlog.package.name}* > MD5SUM)" />
+ <echo message="Creating 'latest' link..." />
+ <exec program="${ssh.program}" commandline="${ssh.args} ${deploy.host} ln -nfs ${nlog.package.name} web/www.nlog-project.org/html/snapshots/latest" />
+ <echo message="Done." />
+ </target>
+
+ <target name="clean_all" depends="clean_examples">
+ <delete>
+ <fileset basedir="build">
+ <include name="**/*" />
+ <include name="*" />
+ <exclude name="readme.txt" />
+ </fileset>
+ </delete>
+ </target>
+
+ <target name="snapshot" depends="clean_all, sync-vs-projects, allframeworksdebugandrelease, source_snapshot, help, installer">
+ </target>
+
+ <target name="publish_snapshot" depends="snapshot, upload_snapshot, upload_web_snapshot">
+ </target>
+
+ <target name="webxmlwithsyntax">
+ <mkdir dir="build/doc/webxmlwithsyntax" />
+ <exec program="${ndocsyntax.path}"
+ commandline="-outDir build/doc/webxmlwithsyntax web/*.xml"
+ workingdir="." useruntimeengine="true" />
+ <exec program="${ndocsyntax.path}"
+ commandline="-outDir build/doc/webxmlwithsyntax web/*.xsl"
+ workingdir="." useruntimeengine="true" />
+ </target>
+
+ <target name="website" depends="xmldoc, webxmlwithsyntax">
+ <property name="webbuild.dir" value="${path::combine(project::get-base-directory(),'build/doc/web')}" />
+ <property name="web.buildmode" value="web" />
+ <property name="web.sourceforge" value="1" />
+ <call target="buildwebsite" />
+ <copy file="build/doc/web/introduction.html" tofile="build/doc/web/index.html" />
+ </target>
+
+ <target name="helpwebsite" depends="xmldoc, webxmlwithsyntax">
+ <property name="webbuild.dir" value="${path::combine(project::get-base-directory(),'build/doc/helpweb')}" />
+ <property name="web.buildmode" value="help" />
+ <property name="web.sourceforge" value="0" />
+ <call target="buildwebsite" />
+ </target>
+
+ <target name="buildwebsite" depends="clean_examples">
+ <mkdir dir="${webbuild.dir}" />
+ <mkdir dir="${webbuild.dir}/examples" />
+
+ <copy todir="${webbuild.dir}">
+ <fileset basedir="web">
+ <include name="*.css" />
+ <include name="*.png" />
+ <include name="*.jpg" />
+ <include name="*.gif" />
+ </fileset>
+ </copy>
+
+ <copy todir="${webbuild.dir}/examples">
+ <fileset basedir="examples">
+ <include name="**/*" />
+ </fileset>
+ </copy>
+
+ <style out="${webbuild.dir}/targets.html" style="web/targets.xsl" in="build/doc/doc.xml">
+ <parameters>
+ <parameter name="build_time" value="${buildtime}" />
+ <parameter name="nlog_package" value="${nlog.package.name}" />
+ <parameter name="external-base" value="${webbuild.dir}" />
+ <parameter name="file_extension" value="html" />
+ <parameter name="sourceforge" value="${web.sourceforge}" />
+ <parameter name="page_id_override" value="documentation" />
+ <parameter name="subpage_id_override" value="targets" />
+ <parameter name="mode" value="${web.buildmode}" />
+ </parameters>
+ </style>
+
+ <style out="${webbuild.dir}/layoutrenderers.html" style="web/layoutrenderers.xsl" in="build/doc/doc.xml">
+ <parameters>
+ <parameter name="build_time" value="${buildtime}" />
+ <parameter name="nlog_package" value="${nlog.package.name}" />
+ <parameter name="external-base" value="${webbuild.dir}" />
+ <parameter name="file_extension" value="html" />
+ <parameter name="sourceforge" value="${web.sourceforge}" />
+ <parameter name="page_id_override" value="documentation" />
+ <parameter name="subpage_id_override" value="layoutrenderers" />
+ <parameter name="mode" value="${web.buildmode}" />
+ </parameters>
+ </style>
+
+ <style out="${webbuild.dir}/layouts.html" style="web/layouts.xsl" in="build/doc/doc.xml">
+ <parameters>
+ <parameter name="build_time" value="${buildtime}" />
+ <parameter name="nlog_package" value="${nlog.package.name}" />
+ <parameter name="external-base" value="${webbuild.dir}" />
+ <parameter name="file_extension" value="html" />
+ <parameter name="sourceforge" value="${web.sourceforge}" />
+ <parameter name="page_id_override" value="documentation" />
+ <parameter name="subpage_id_override" value="layouts" />
+ <parameter name="mode" value="${web.buildmode}" />
+ </parameters>
+ </style>
+
+ <style out="${webbuild.dir}/filters.html" style="web/filters.xsl" in="build/doc/doc.xml">
+ <parameters>
+ <parameter name="build_time" value="${buildtime}" />
+ <parameter name="nlog_package" value="${nlog.package.name}" />
+ <parameter name="external-base" value="${webbuild.dir}" />
+ <parameter name="file_extension" value="html" />
+ <parameter name="sourceforge" value="${web.sourceforge}" />
+ <parameter name="page_id_override" value="documentation" />
+ <parameter name="subpage_id_override" value="filters" />
+ <parameter name="mode" value="${web.buildmode}" />
+ </parameters>
+ </style>
+
+ <style out="${webbuild.dir}/conditions.html" style="web/conditions.xsl" in="build/doc/doc.xml">
+ <parameters>
+ <parameter name="build_time" value="${buildtime}" />
+ <parameter name="nlog_package" value="${nlog.package.name}" />
+ <parameter name="external-base" value="${webbuild.dir}" />
+ <parameter name="file_extension" value="html" />
+ <parameter name="sourceforge" value="${web.sourceforge}" />
+ <parameter name="page_id_override" value="documentation" />
+ <parameter name="subpage_id_override" value="conditions" />
+ <parameter name="mode" value="${web.buildmode}" />
+ </parameters>
+ </style>
+
+ <foreach item="String" in="${nlog.targetNames}" delim="," property="t">
+ <style out="${webbuild.dir}/target.${t}.html" style="web/targets.xsl" in="build/doc/doc.xml">
+ <parameters>
+ <parameter name="build_time" value="${buildtime}" />
+ <parameter name="nlog_package" value="${nlog.package.name}" />
+ <parameter name="external-base" value="${webbuild.dir}" />
+ <parameter name="file_extension" value="html" />
+ <parameter name="sourceforge" value="${web.sourceforge}" />
+ <parameter name="page_id_override" value="documentation" />
+ <parameter name="subpage_id_override" value="targets" />
+ <parameter name="mode" value="${web.buildmode}" />
+ <parameter name="target_name" value="${t}" />
+ </parameters>
+ </style>
+ </foreach>
+
+ <foreach item="String" in="${nlog.layoutRendererNames}" delim="," property="t">
+ <style out="${webbuild.dir}/lr.${t}.html" style="web/layoutrenderers.xsl" in="build/doc/doc.xml">
+ <parameters>
+ <parameter name="build_time" value="${buildtime}" />
+ <parameter name="nlog_package" value="${nlog.package.name}" />
+ <parameter name="external-base" value="${webbuild.dir}" />
+ <parameter name="file_extension" value="html" />
+ <parameter name="sourceforge" value="${web.sourceforge}" />
+ <parameter name="page_id_override" value="documentation" />
+ <parameter name="subpage_id_override" value="layoutrenderers" />
+ <parameter name="mode" value="${web.buildmode}" />
+ <parameter name="lr_name" value="${t}" />
+ </parameters>
+ </style>
+ </foreach>
+
+ <foreach item="String" in="${nlog.layoutNames}" delim="," property="t">
+ <style out="${webbuild.dir}/layout.${t}.html" style="web/layouts.xsl" in="build/doc/doc.xml">
+ <parameters>
+ <parameter name="build_time" value="${buildtime}" />
+ <parameter name="nlog_package" value="${nlog.package.name}" />
+ <parameter name="external-base" value="${webbuild.dir}" />
+ <parameter name="file_extension" value="html" />
+ <parameter name="sourceforge" value="${web.sourceforge}" />
+ <parameter name="page_id_override" value="documentation" />
+ <parameter name="subpage_id_override" value="layouts" />
+ <parameter name="mode" value="${web.buildmode}" />
+ <parameter name="l_name" value="${t}" />
+ </parameters>
+ </style>
+ </foreach>
+
+ <foreach item="String" in="${nlog.filterNames}" delim="," property="t">
+ <style out="${webbuild.dir}/filter.${t}.html" style="web/filters.xsl" in="build/doc/doc.xml">
+ <parameters>
+ <parameter name="build_time" value="${buildtime}" />
+ <parameter name="nlog_package" value="${nlog.package.name}" />
+ <parameter name="external-base" value="${webbuild.dir}" />
+ <parameter name="file_extension" value="html" />
+ <parameter name="sourceforge" value="${web.sourceforge}" />
+ <parameter name="page_id_override" value="documentation" />
+ <parameter name="subpage_id_override" value="filters" />
+ <parameter name="mode" value="${web.buildmode}" />
+ <parameter name="filter_name" value="${t}" />
+ </parameters>
+ </style>
+ </foreach>
+
+ <style destdir="${webbuild.dir}" style="web/style.xsl">
+ <infiles basedir="build/doc/webxmlwithsyntax">
+ <include name="*.xml" />
+ <exclude name="common.en.xml" />
+ </infiles>
+ <parameters>
+ <parameter name="build_time" value="${buildtime}" />
+ <parameter name="nlog_package" value="${nlog.package.name}" />
+ <parameter name="external-base" value="${webbuild.dir}" />
+ <parameter name="file_extension" value="html" />
+ <parameter name="sourceforge" value="${web.sourceforge}" />
+ <parameter name="mode" value="${web.buildmode}" />
+ </parameters>
+ </style>
+ </target>
+
+ <target name="load-clover">
+ <loadtasks assembly="${clover.home}/CloverNAnt-0.85.dll" />
+ </target>
+
+ <target name="clover" depends="load-clover">
+ <property name="clover.enabled" value="true" />
+ <call target="configure" />
+ <call target="clean" />
+ <delete file="${clover.build.dir}/clover.cdb" failonerror="false" />
+ <clover-setup
+ initstring="${clover.build.dir}/clover.cdb"
+ builddir="${clover.build.dir}"
+ enabled="${clover.enabled}"
+ flushinterval="100">
+ <fileset basedir="src">
+ <include name="**/*" />
+ <exclude name="NLog.UnitTests.Web/**/*" />
+ </fileset>
+ </clover-setup>
+ <call target="build" />
+ <call target="nunit2report" />
+ <clover-report>
+ <current title="NLog Coverage" output="${clover.report.dir}">
+ <format type="html" />
+ </current>
+ </clover-report>
+ </target>
+
+ <target name="load-nunit2report">
+ <loadtasks assembly="tools/nunit2report/NAnt.NUnit2ReportTasks.dll" />
+ </target>
+
+ <target name="setup_unittest_website">
+ <mkiisdir dirpath="${project::get-base-directory()}/nlogtest" vdirname="nlogtest"
+ authntlm="false"
+ authanonymous="true"
+ authbasic="false"
+ failonerror="false"
+ />
+ </target>
+
+ <target name="nunit2report" depends="load-nunit2report, test">
+ <nunit2report format="frames" todir="${nunit2.report.dir}" verbose="true">
+ <fileset>
+ <include name="build/${buildsubdir}/test_results_xml/*.xml" />
+ </fileset>
+ </nunit2report>
+ </target>
+
+ <target name="publish_nunit2report" depends="nunit2report">
+ <zip zipfile="web.zip">
+ <fileset basedir="${nunit2.report.dir}">
+ <include name="**/*" />
+ </fileset>
+ </zip>
+ <echo message="Uploading web.zip and tools/web_install.sh to ${deploy.host}..." />
+ <exec program="${scp.program}" commandline="${scp.args} web.zip tools/web_install.sh ${deploy.host}:." workingdir="." />
+ <echo message="Spawning web_install.sh..." />
+ <exec program="${ssh.program}" commandline="${ssh.args} ${deploy.host} dos2unix web_install.sh && /bin/bash web_install.sh ${webserver.deploy.dir}/nunit2report" workingdir="." />
+ <echo message="NUnit2report results deployed." />
+ </target>
+
+ <target name="deploy-web" depends="website">
+ <delete file="web.zip" if="${file::exists('web.zip')}" />
+ <zip zipfile="web.zip" stampdatetime="${datetime::now()}" includeemptydirs="true">
+ <fileset basedir="build/doc/web">
+ <include name="**/*" />
+ <exclude name="**/.svn" />
+ <exclude name="**/.svn/**" />
+ <exclude name="**/_svn" />
+ <exclude name="**/_svn/**" />
+ <exclude name="**/*.swp" />
+ </fileset>
+ </zip>
+ <echo message="Uploading web.zip and tools/web_install.sh to ${deploy.host}..." />
+ <exec program="${scp.program}" commandline="${scp.args} web.zip tools/web_install.sh ${deploy.host}:." workingdir="." />
+ <echo message="Spawning web_install.sh..." />
+ <exec program="${ssh.program}" commandline="${ssh.args} ${deploy.host} dos2unix web_install.sh && /bin/bash web_install.sh ${webserver.deploy.dir}" workingdir="." />
+ <!-- <delete file="web.zip" /> -->
+ </target>
+
+ <target name="sourceforge_release">
+ <exec program="nant" commandline="publish_nunit2report" />
+ <exec program="nant" commandline="clover test publish_clover" />
+ </target>
+
+ <target name="sync-vs-projects">
+ <csc target="library" output="build/SyncVSProjectItems.dll">
+ <sources basedir="tools">
+ <include name="SyncVSProjectItems.cs" />
+ </sources>
+ <references>
+ <include name="${nant::get-base-directory()}/NAnt.Core.dll" />
+ </references>
+ </csc>
+ <loadtasks assembly="build/SyncVSProjectItems.dll" />
+ <sync-vs-project-items>
+ <project-files basedir="src/NLog">
+ <include name="*.csproj" />
+ <include name="*.csdproj" />
+ </project-files>
+ <source-files basedir="src/NLog">
+ <include name="**/*.cs" />
+ </source-files>
+ </sync-vs-project-items>
+
+ <sync-vs-project-items>
+ <project-files basedir="src/NLog.ComInterop">
+ <include name="*.csproj" />
+ <include name="*.csdproj" />
+ </project-files>
+ <source-files basedir="src/NLog.ComInterop">
+ <include name="**/*.cs" />
+ </source-files>
+ </sync-vs-project-items>
+
+ <sync-vs-project-items>
+ <project-files basedir="tests/NLog.Test">
+ <include name="*.csproj" />
+ <include name="*.csdproj" />
+ </project-files>
+ <source-files basedir="tests/NLog.Test">
+ <include name="**/*.cs" />
+ </source-files>
+ </sync-vs-project-items>
+
+ <sync-vs-project-items>
+ <project-files basedir="tests/NLog.UnitTests">
+ <include name="*.csproj" />
+ <include name="*.csdproj" />
+ </project-files>
+ <source-files basedir="tests/NLog.UnitTests">
+ <include name="**/*.cs" />
+ </source-files>
+ </sync-vs-project-items>
+ </target>
+
+ <target name="clean_examples">
+ <delete>
+ <fileset basedir="examples">
+ <include name="**/*.suo" />
+ <include name="**/bin/**/*" />
+ <include name="**/obj/**/*" />
+ <include name="**/bin" />
+ <include name="**/obj" />
+ <include name="**/*proj.user" />
+ </fileset>
+ </delete>
+ </target>
+</project>
diff --git a/NLog.hhp b/NLog.hhp
new file mode 100644
index 0000000..a69bf73
--- /dev/null
+++ b/NLog.hhp
@@ -0,0 +1,21 @@
+[OPTIONS]
+Auto Index=Yes
+Compatibility=1.1 or later
+Compiled file=NLog-Sandcastle-July-CTP.chm
+Contents file=Test.hhc
+Default topic=html\helpindex.html
+Display compile progress=No
+Index file=html\helpindex.html
+Language=0x409 English (United States)
+Title=NLog Documentation
+
+
+[FILES]
+art\*.gif
+html\*.htm
+html\*.html
+scripts\*.js
+styles\*.css
+
+[INFOTYPES]
+
diff --git a/NLog.ndoc b/NLog.ndoc
new file mode 100644
index 0000000..4e32907
--- /dev/null
+++ b/NLog.ndoc
@@ -0,0 +1,62 @@
+<?xml version="1.0" ?>
+<project SchemaVersion="1.3">
+ <assemblies>
+ <assembly location="./build/doc/NLog.dll" documentation="./build/doc/NLog.xml" />
+ </assemblies>
+ <documenters>
+ <documenter name="JavaDoc">
+ <property name="OutputDirectory" value="../../../doc/" />
+ </documenter>
+ <documenter name="LaTeX">
+ <property name="OutputDirectory" value="./doc/" />
+ <property name="TextFileFullName" value="Documentation.tex" />
+ <property name="TexFileBaseName" value="Documentation" />
+ <property name="LatexCompiler" value="latex" />
+ <property name="TexFileFullPath" value="./doc/Documentation.tex" />
+ </documenter>
+ <documenter name="LinearHtml">
+ <property name="OutputDirectory" value="./doc/" />
+ <property name="Title" value="An NDoc Documented Class Library" />
+ </documenter>
+ <documenter name="MSDN">
+ <property name="OutputDirectory" value="./build/doc/help/" />
+ <property name="HtmlHelpName" value="NLog" />
+ <property name="Title" value="NLog Logging Library" />
+ <property name="ShowVisualBasic" value="True" />
+ <property name="SdkLinksOnWeb" value="True" />
+ <property name="IncludeFavorites" value="True" />
+ <property name="RootPageTOCName" value="Welcome to NLog" />
+ <property name="RootPageFileName" value="./build/doc/helpweb/helpindex.html" />
+ <property name="BinaryTOC" value="False" />
+ <property name="FilesToInclude" value="targets.html|filters.html|layoutrenderers.html" />
+ <property name="AdditionalContentResourceDirectory" value="./build/doc/helpweb/" />
+ <property name="ExtensibilityStylesheet" value="./build/doc/syntax.xsl" />
+ <property name="ShowMissingParams" value="True" />
+ <property name="ShowMissingReturns" value="True" />
+ <property name="DocumentInheritedFrameworkMembers" value="False" />
+ <property name="AssemblyVersionInfo" value="AssemblyVersion" />
+ <property name="CopyrightText" value="Copyright (c) 2004-2006 by Jaroslaw Kowalski" />
+ <property name="CopyrightHref" value="http://www.nlog-project.org/" />
+ <property name="Preliminary" value="True" />
+ <property name="InstanceMembersDefaultToSafe" value="True" />
+ </documenter>
+ <documenter name="MSDN 2003">
+ <property name="OutputDirectory" value="./doc/" />
+ <property name="Title" value="An NDoc Documented Class Library" />
+ <property name="ExtensibilityStylesheet" value="./syntax.xsl" />
+ </documenter>
+ <documenter name="VS.NET 2003">
+ <property name="OutputDirectory" value="./doc/" />
+ <property name="HtmlHelpName" value="Documentation" />
+ <property name="Title" value="An NDoc documented library" />
+ <property name="ExtensibilityStylesheet" value="./syntax.xsl" />
+ </documenter>
+ <documenter name="XML">
+ <property name="OutputFile" value="./build/doc/doc.xml" />
+ <property name="ShowMissingSummaries" value="True" />
+ <property name="DocumentInheritedFrameworkMembers" value="False" />
+ <property name="DocumentAttributes" value="True" />
+ <property name="ShowTypeIdInAttributes" value="True" />
+ </documenter>
+ </documenters>
+</project>
diff --git a/NLog.version b/NLog.version
new file mode 100644
index 0000000..f4ec564
--- /dev/null
+++ b/NLog.version
@@ -0,0 +1 @@
+1.0.0.505
diff --git a/NLog.vs2003.sln b/NLog.vs2003.sln
new file mode 100644
index 0000000..d4bd7cf
--- /dev/null
+++ b/NLog.vs2003.sln
@@ -0,0 +1,51 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "NLog.VBTest.vs2003", "tests\NLog.VBTest\NLog.VBTest.vs2003.vbproj", "{2993B4C3-A0EE-43C8-84EB-97920E69B292}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.vs2003", "src\NLog\NLog.vs2003.csproj", "{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.Test.vs2003", "tests\NLog.Test\NLog.Test.vs2003.csproj", "{5EC49108-97AE-40EA-B550-8960E4522718}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.ComInterop.vs2003", "src\NLog.ComInterop\NLog.ComInterop.vs2003.csproj", "{B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {2993B4C3-A0EE-43C8-84EB-97920E69B292}.Debug.ActiveCfg = Debug|.NET
+ {2993B4C3-A0EE-43C8-84EB-97920E69B292}.Debug.Build.0 = Debug|.NET
+ {2993B4C3-A0EE-43C8-84EB-97920E69B292}.Release.ActiveCfg = Release|.NET
+ {2993B4C3-A0EE-43C8-84EB-97920E69B292}.Release.Build.0 = Release|.NET
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug.ActiveCfg = Debug|.NET
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug.Build.0 = Debug|.NET
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release.ActiveCfg = Release|.NET
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release.Build.0 = Release|.NET
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Debug.ActiveCfg = Debug|.NET
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Debug.Build.0 = Debug|.NET
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Release.ActiveCfg = Release|.NET
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Release.Build.0 = Release|.NET
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Debug.ActiveCfg = Debug|.NET
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Debug.Build.0 = Debug|.NET
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Release.ActiveCfg = Release|.NET
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Release.Build.0 = Release|.NET
+ EndGlobalSection
+ GlobalSection(SolutionItems) = postSolution
+ NLog.build = NLog.build
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+ GlobalSection(DPCodeReviewSolutionGUID) = preSolution
+ DPCodeReviewSolutionGUID = {C4811F53-E779-47F0-8C06-71551FBDB047}
+ EndGlobalSection
+EndGlobal
diff --git a/NLog.vs2005.sln b/NLog.vs2005.sln
new file mode 100644
index 0000000..52591c0
--- /dev/null
+++ b/NLog.vs2005.sln
@@ -0,0 +1,68 @@
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.vs2005", "src\NLog\NLog.vs2005.csproj", "{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.Test.vs2005", "tests\NLog.Test\NLog.Test.vs2005.csproj", "{5EC49108-97AE-40EA-B550-8960E4522718}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.ComInterop.vs2005", "src\NLog.ComInterop\NLog.ComInterop.vs2005.csproj", "{B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MakeNLogXSD.vs2005", "tools\MakeNLogXSD\MakeNLogXSD.vs2005.csproj", "{BB32EC17-234D-477D-AC37-96EB19A52018}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|Win32 = Debug|Win32
+ Release|Any CPU = Release|Any CPU
+ Release|Mixed Platforms = Release|Mixed Platforms
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release|Any CPU.Build.0 = Release|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release|Win32.ActiveCfg = Release|Any CPU
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Release|Win32.ActiveCfg = Release|Any CPU
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Release|Win32.ActiveCfg = Release|Any CPU
+ {BB32EC17-234D-477D-AC37-96EB19A52018}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BB32EC17-234D-477D-AC37-96EB19A52018}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BB32EC17-234D-477D-AC37-96EB19A52018}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {BB32EC17-234D-477D-AC37-96EB19A52018}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {BB32EC17-234D-477D-AC37-96EB19A52018}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {BB32EC17-234D-477D-AC37-96EB19A52018}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BB32EC17-234D-477D-AC37-96EB19A52018}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BB32EC17-234D-477D-AC37-96EB19A52018}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {BB32EC17-234D-477D-AC37-96EB19A52018}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {BB32EC17-234D-477D-AC37-96EB19A52018}.Release|Win32.ActiveCfg = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(DPCodeReviewSolutionGUID) = preSolution
+ DPCodeReviewSolutionGUID = {C4811F53-E779-47F0-8C06-71551FBDB047}
+ EndGlobalSection
+EndGlobal
diff --git a/NLogC.vs2003.sln b/NLogC.vs2003.sln
new file mode 100644
index 0000000..19bb4f0
--- /dev/null
+++ b/NLogC.vs2003.sln
@@ -0,0 +1,48 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NLogC.vs2003", "src\NLogC\NLogC.vs2003.vcproj", "{63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.vs2003", "src\NLog\NLog.vs2003.csproj", "{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NLogCTest.vs2003", "tests\NLogCTest\NLogCTest.vs2003.vcproj", "{3A3B8573-0A64-414D-9E8D-9F1982004299}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.ComInterop.vs2003", "src\NLog.ComInterop\NLog.ComInterop.vs2003.csproj", "{B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Debug.ActiveCfg = Debug|Win32
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Debug.Build.0 = Debug|Win32
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Release.ActiveCfg = Release|Win32
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Release.Build.0 = Release|Win32
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug.ActiveCfg = Debug|.NET
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug.Build.0 = Debug|.NET
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release.ActiveCfg = Release|.NET
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release.Build.0 = Release|.NET
+ {3A3B8573-0A64-414D-9E8D-9F1982004299}.Debug.ActiveCfg = Debug|Win32
+ {3A3B8573-0A64-414D-9E8D-9F1982004299}.Debug.Build.0 = Debug|Win32
+ {3A3B8573-0A64-414D-9E8D-9F1982004299}.Release.ActiveCfg = Release|Win32
+ {3A3B8573-0A64-414D-9E8D-9F1982004299}.Release.Build.0 = Release|Win32
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Debug.ActiveCfg = Debug|.NET
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Debug.Build.0 = Debug|.NET
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Release.ActiveCfg = Release|.NET
+ {B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}.Release.Build.0 = Release|.NET
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+ GlobalSection(DPCodeReviewSolutionGUID) = preSolution
+ DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000}
+ EndGlobalSection
+EndGlobal
diff --git a/NLogC.vs2005.sln b/NLogC.vs2005.sln
new file mode 100644
index 0000000..ffc5568
--- /dev/null
+++ b/NLogC.vs2005.sln
@@ -0,0 +1,44 @@
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.vs2005", "src\NLog\NLog.vs2005.csproj", "{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NLogC.vs2005", "src\NLogC\NLogC.vs2005.vcproj", "{63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|Win32 = Debug|Win32
+ Release|Any CPU = Release|Any CPU
+ Release|Mixed Platforms = Release|Mixed Platforms
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release|Any CPU.Build.0 = Release|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release|Win32.ActiveCfg = Release|Any CPU
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Debug|Win32.Build.0 = Debug|Win32
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Release|Any CPU.ActiveCfg = Release|Win32
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Release|Win32.ActiveCfg = Release|Win32
+ {63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(DPCodeReviewSolutionGUID) = preSolution
+ DPCodeReviewSolutionGUID = {C4811F53-E779-47F0-8C06-71551FBDB047}
+ EndGlobalSection
+EndGlobal
diff --git a/NLogCF.vs2003.sln b/NLogCF.vs2003.sln
new file mode 100644
index 0000000..fb8f94e
--- /dev/null
+++ b/NLogCF.vs2003.sln
@@ -0,0 +1,36 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{20D4826A-C6FA-45DB-90F4-C717570B9F32}") = "NLog.vs2003", "src\NLog\NLog.vs2003.csdproj", "{4125C120-539F-4C80-B3D2-35FFF271998A}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{20D4826A-C6FA-45DB-90F4-C717570B9F32}") = "NLog.CFTest.vs2003", "tests\NLog.CFTest\NLog.CFTest.vs2003.csdproj", "{F8DA3276-560A-490C-AF75-E27307887CA3}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {4125C120-539F-4C80-B3D2-35FFF271998A}.Debug.ActiveCfg = Debug|Windows CE
+ {4125C120-539F-4C80-B3D2-35FFF271998A}.Debug.Build.0 = Debug|Windows CE
+ {4125C120-539F-4C80-B3D2-35FFF271998A}.Debug.Deploy.0 = Debug|Windows CE
+ {4125C120-539F-4C80-B3D2-35FFF271998A}.Release.ActiveCfg = Release|Windows CE
+ {4125C120-539F-4C80-B3D2-35FFF271998A}.Release.Build.0 = Release|Windows CE
+ {4125C120-539F-4C80-B3D2-35FFF271998A}.Release.Deploy.0 = Release|Windows CE
+ {F8DA3276-560A-490C-AF75-E27307887CA3}.Debug.ActiveCfg = Debug|Pocket PC
+ {F8DA3276-560A-490C-AF75-E27307887CA3}.Debug.Build.0 = Debug|Pocket PC
+ {F8DA3276-560A-490C-AF75-E27307887CA3}.Debug.Deploy.0 = Debug|Pocket PC
+ {F8DA3276-560A-490C-AF75-E27307887CA3}.Release.ActiveCfg = Release|Pocket PC
+ {F8DA3276-560A-490C-AF75-E27307887CA3}.Release.Build.0 = Release|Pocket PC
+ {F8DA3276-560A-490C-AF75-E27307887CA3}.Release.Deploy.0 = Release|Pocket PC
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+ GlobalSection(DPCodeReviewSolutionGUID) = preSolution
+ DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000}
+ EndGlobalSection
+EndGlobal
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..a36da2b
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,41 @@
+NLog
+
+What is it?
+-----------
+NLog is a .NET logging library designed with simplicity and flexibility in mind.
+With NLog you can process diagnostic messages emitted from any .NET language, augment
+them with contextual information, format them according to your preference and send
+them to one or more targets.
+
+The API (application programming interface) is similar to log4net, and the configuration
+is very simple. NLog uses a routing table while log4net uses a logger hierarchy with
+attachable appenders. This makes NLog's configuration very easy to read and maintain.
+
+NLog is licensed under the terms of BSD license, which permits commercial use and the
+source code is available to anyone at no cost. Everyone is encouraged to test it and
+report feedback to the mailing list.
+
+NLog supports .NET, C/C++ and COM interop API so that all your application components
+including legacy modules written in C++/COM can send their messages through a common
+log routing engine.
+
+The .NET API is very fast at filtering messages, so that you can keep your logging
+instructions in code and let NLog filter them out at runtime. NLog can filter out as
+many as 150 million logging instructions per second on a single-CPU 1.6 GHz laptop.
+Add that to asynchronous processing and other wrappers and you'll get a very
+powerful and scalable logging tool.
+
+The Latest Version
+------------------
+Details of the latest version can be found on the NLog project web site
+http://www.nlog-project.org/
+
+Documentation
+-------------
+Documentation is available in HTML format on the
+project website (http://www.nlog-project.org/)
+
+License
+-------
+NLog is licensed under the terms of BSD license which permits its usage
+in open-source and proprietary software. See LICENSE.txt for details.
diff --git a/build/README.txt b/build/README.txt
new file mode 100644
index 0000000..1865a7c
--- /dev/null
+++ b/build/README.txt
@@ -0,0 +1 @@
+Output binaries will be created here. Do not delete this directory.
diff --git a/examples/ExtendingLoggers/InheritFromLogger/InheritFromLogger.csproj b/examples/ExtendingLoggers/InheritFromLogger/InheritFromLogger.csproj
new file mode 100644
index 0000000..b8ab621
--- /dev/null
+++ b/examples/ExtendingLoggers/InheritFromLogger/InheritFromLogger.csproj
@@ -0,0 +1,53 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{E9EC09E9-F6F6-4CEA-923C-A8D580BF73D9}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>InheritFromLogger</RootNamespace>
+ <AssemblyName>InheritFromLogger</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL" />
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="NLog.config">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
diff --git a/examples/ExtendingLoggers/InheritFromLogger/InheritFromLogger.sln b/examples/ExtendingLoggers/InheritFromLogger/InheritFromLogger.sln
new file mode 100644
index 0000000..e01f761
--- /dev/null
+++ b/examples/ExtendingLoggers/InheritFromLogger/InheritFromLogger.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InheritFromLogger", "InheritFromLogger.csproj", "{E9EC09E9-F6F6-4CEA-923C-A8D580BF73D9}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E9EC09E9-F6F6-4CEA-923C-A8D580BF73D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E9EC09E9-F6F6-4CEA-923C-A8D580BF73D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E9EC09E9-F6F6-4CEA-923C-A8D580BF73D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E9EC09E9-F6F6-4CEA-923C-A8D580BF73D9}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/ExtendingLoggers/InheritFromLogger/NLog.config b/examples/ExtendingLoggers/InheritFromLogger/NLog.config
new file mode 100644
index 0000000..131adcd
--- /dev/null
+++ b/examples/ExtendingLoggers/InheritFromLogger/NLog.config
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="eventlog"
+ xsi:type="EventLog"
+ eventID="${event-context:EventID}"
+ source="NLog Example"
+ layout="${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="eventlog" />
+ </rules>
+</nlog>
diff --git a/examples/ExtendingLoggers/InheritFromLogger/Program.cs b/examples/ExtendingLoggers/InheritFromLogger/Program.cs
new file mode 100644
index 0000000..0225580
--- /dev/null
+++ b/examples/ExtendingLoggers/InheritFromLogger/Program.cs
@@ -0,0 +1,87 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using NLog;
+
+namespace InheritFromLogger
+{
+ /// <summary>
+ /// Provides methods to write messages with event IDs - useful for the Event Log target
+ /// Inherits from the Logger class.
+ /// </summary>
+ public class LoggerWithEventID : Logger
+ {
+ public LoggerWithEventID()
+ {
+ }
+
+ // additional method that takes eventID as an argument
+ public void DebugWithEventID(int eventID, string message, params object[] args)
+ {
+ if (IsDebugEnabled)
+ {
+ // create log event
+ LogEventInfo lei = new LogEventInfo(LogLevel.Debug, Name, null, message, args);
+
+ // set the per-log context data
+ // this data can be retrieved using ${event-context:EventID}
+ lei.Context["EventID"] = eventID;
+
+ // log the message
+ base.Log(typeof(LoggerWithEventID), lei);
+ }
+ }
+
+ // other methods omitted for brevity
+ }
+
+ class Program
+ {
+ // get the current class logger as an instance of LoggerWithEventID class
+
+ private static LoggerWithEventID LoggerWithEventID = (LoggerWithEventID)LogManager.GetCurrentClassLogger(typeof(LoggerWithEventID));
+
+ static void Main(string[] args)
+ {
+ // this writes 5 messages to the Event Log, each with a different EventID
+
+ LoggerWithEventID.DebugWithEventID(123, "message 1", 1, 2, 3);
+ LoggerWithEventID.DebugWithEventID(124, "message 2", 1, 2, 3);
+ LoggerWithEventID.DebugWithEventID(125, "message 3", 1, 2, 3);
+ LoggerWithEventID.DebugWithEventID(126, "message 4", 1, 2, 3);
+ LoggerWithEventID.DebugWithEventID(127, "message 5", 1, 2, 3);
+ }
+ }
+}
diff --git a/examples/ExtendingLoggers/InheritFromLogger/Properties/AssemblyInfo.cs b/examples/ExtendingLoggers/InheritFromLogger/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..af76b1b
--- /dev/null
+++ b/examples/ExtendingLoggers/InheritFromLogger/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("InheritFromLogger")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("InheritFromLogger")]
+[assembly: AssemblyCopyright("Copyright © Jaroslaw Kowalski. 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("6be26d09-c79f-4572-8890-68b70d4fd193")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/examples/ExtendingLoggers/LoggerWrapper/LoggerWrapper.csproj b/examples/ExtendingLoggers/LoggerWrapper/LoggerWrapper.csproj
new file mode 100644
index 0000000..fc8ac61
--- /dev/null
+++ b/examples/ExtendingLoggers/LoggerWrapper/LoggerWrapper.csproj
@@ -0,0 +1,53 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{B8526875-5F24-4225-A93D-B4FE6099F616}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>LoggerWrapper</RootNamespace>
+ <AssemblyName>LoggerWrapper</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL" />
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="NLog.config">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
diff --git a/examples/ExtendingLoggers/LoggerWrapper/LoggerWrapper.sln b/examples/ExtendingLoggers/LoggerWrapper/LoggerWrapper.sln
new file mode 100644
index 0000000..588805f
--- /dev/null
+++ b/examples/ExtendingLoggers/LoggerWrapper/LoggerWrapper.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoggerWrapper", "LoggerWrapper.csproj", "{B8526875-5F24-4225-A93D-B4FE6099F616}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B8526875-5F24-4225-A93D-B4FE6099F616}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B8526875-5F24-4225-A93D-B4FE6099F616}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B8526875-5F24-4225-A93D-B4FE6099F616}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B8526875-5F24-4225-A93D-B4FE6099F616}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/ExtendingLoggers/LoggerWrapper/NLog.config b/examples/ExtendingLoggers/LoggerWrapper/NLog.config
new file mode 100644
index 0000000..b866d5a
--- /dev/null
+++ b/examples/ExtendingLoggers/LoggerWrapper/NLog.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="console" xsi:type="Console" layout="${callsite} ${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="console" />
+ </rules>
+</nlog>
diff --git a/examples/ExtendingLoggers/LoggerWrapper/Program.cs b/examples/ExtendingLoggers/LoggerWrapper/Program.cs
new file mode 100644
index 0000000..8675360
--- /dev/null
+++ b/examples/ExtendingLoggers/LoggerWrapper/Program.cs
@@ -0,0 +1,85 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using NLog;
+
+namespace LoggerWrapper
+{
+ /// <summary>
+ /// Provides methods to write messages with event IDs - useful for the Event Log target.
+ /// Wraps a Logger instance.
+ /// </summary>
+ class MyLogger
+ {
+ private Logger _logger;
+
+ public MyLogger(string name)
+ {
+ _logger = LogManager.GetLogger(name);
+ }
+
+ public void WriteMessage(string eventID, string message)
+ {
+ ///
+ /// create log event from the passed message
+ ///
+ LogEventInfo logEvent = new LogEventInfo(LogLevel.Info, _logger.Name, message);
+
+ //
+ // set event-specific context parameter
+ // this context parameter can be retrieved using ${event-context:EventID}
+ //
+ logEvent.Context["EventID"] = eventID;
+
+ //
+ // Call the Log() method. It is important to pass typeof(MyLogger) as the
+ // first parameter. If you don't, ${callsite} and other callstack-related
+ // layout renderers will not work properly.
+ //
+
+ _logger.Log(typeof(MyLogger), logEvent);
+ }
+ }
+
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ MyLogger l = new MyLogger("uuu");
+
+ l.WriteMessage("1234", "message");
+ }
+ }
+}
diff --git a/examples/ExtendingLoggers/LoggerWrapper/Properties/AssemblyInfo.cs b/examples/ExtendingLoggers/LoggerWrapper/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c6a2d20
--- /dev/null
+++ b/examples/ExtendingLoggers/LoggerWrapper/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("LoggerWrapper")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("LoggerWrapper")]
+[assembly: AssemblyCopyright("Copyright © Jaroslaw Kowalski 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7d6322a9-8f43-4ca5-bc1e-a5b53cf64706")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/examples/ExtendingLoggers/README.html b/examples/ExtendingLoggers/README.html
new file mode 100644
index 0000000..69a7742
--- /dev/null
+++ b/examples/ExtendingLoggers/README.html
@@ -0,0 +1,39 @@
+<html>
+ <head>
+ <title>NLog Examples</title>
+ <style type="text/css">
+ body
+ {
+ font-family: Tahoma;
+ font-size: 10pt;
+ }
+ </style>
+ </head>
+ <body>
+ <p>
+ This directory contains examples of extending functionality of loggers. This is needed to pass
+ extra per-call context information to the logging engine. For example, you can pass log event ID
+ that will be written to the Event Log.
+ </p>
+ <p>
+ There are 2 methods of extending loggers:
+ </p>
+ <ul>
+ <li><b>wrapping loggers</b> - the code that wraps Logger is located in the <a href="LoggerWrapper/">LoggerWrapper</a> directory.</li>
+ <li><b>inheriting from loggers</b> - the code that extends the Logger class by inheriting from it can be found in the <a href="InheritFromLogger/">InheritFromLogger</a> directory.</li>
+ </ul>
+ <p>
+ Both methods construct a <code>LogEventInfo</code> object and pass it to the Log() method of the logger. It is important
+ to also pass the declaring type of the method that is invoked by user code, otherwise the <a href="http://www.nlog-project.org/lr.callsite.html">${callsite}</a>
+ and <a href="http://www.nlog-project.org/lr.stacktrace.html">${stacktrace}</a> layout renderers won't work properly.
+ </p>
+ <p>
+ The examples also demonstrate is the technique of passing additional per-log context information. This is
+ done by adding items to the <code>LogEvent.Context</code> dictionary. This context data can be retrieved
+ and used in layouts with the <code>${event-context}</code> layout renderer.
+ </p>
+ <p>
+ The examples are compatible with <a href="http://www.microsoft.com/vstudio">Visual Studio 2005</a> and can be built with <a href="http://msdn2.microsoft.com/en-us/library/wea2sca5.aspx">MSBuild</a>.
+ </p>
+ </body>
+</html>
diff --git a/examples/targets/Configuration API/ASPNetBufferingWrapper/ASPNetBufferingWrapper.csproj b/examples/targets/Configuration API/ASPNetBufferingWrapper/ASPNetBufferingWrapper.csproj
new file mode 100644
index 0000000..9be28a6
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetBufferingWrapper/ASPNetBufferingWrapper.csproj
@@ -0,0 +1,95 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{18041F69-4814-447B-B170-984E72423D4A}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>ASPNetBufferingWrapper</RootNamespace>
+ <AssemblyName>ASPNetBufferingWrapper</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="System.Web.Mobile" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Global.asax" />
+ <Content Include="NormalPage.aspx" />
+ <Content Include="PageWithWarnings.aspx" />
+ <Content Include="Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Global.asax.cs">
+ <DependentUpon>Global.asax</DependentUpon>
+ </Compile>
+ <Compile Include="NormalPage.aspx.cs">
+ <SubType>ASPXCodeBehind</SubType>
+ <DependentUpon>NormalPage.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="NormalPage.aspx.designer.cs">
+ <DependentUpon>NormalPage.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="PageWithWarnings.aspx.cs">
+ <SubType>ASPXCodeBehind</SubType>
+ <DependentUpon>PageWithWarnings.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="PageWithWarnings.aspx.designer.cs">
+ <DependentUpon>PageWithWarnings.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v8.0\WebApplications\Microsoft.WebApplication.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>False</UseIIS>
+ <AutoAssignPort>True</AutoAssignPort>
+ <DevelopmentServerPort>4778</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>
+ </IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/ASPNetBufferingWrapper/ASPNetBufferingWrapper.sln b/examples/targets/Configuration API/ASPNetBufferingWrapper/ASPNetBufferingWrapper.sln
new file mode 100644
index 0000000..ae5b683
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetBufferingWrapper/ASPNetBufferingWrapper.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASPNetBufferingWrapper", "ASPNetBufferingWrapper.csproj", "{18041F69-4814-447B-B170-984E72423D4A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {18041F69-4814-447B-B170-984E72423D4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {18041F69-4814-447B-B170-984E72423D4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {18041F69-4814-447B-B170-984E72423D4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {18041F69-4814-447B-B170-984E72423D4A}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/ASPNetBufferingWrapper/Global.asax b/examples/targets/Configuration API/ASPNetBufferingWrapper/Global.asax
new file mode 100644
index 0000000..a19bb74
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetBufferingWrapper/Global.asax
@@ -0,0 +1 @@
+<%@ Application Codebehind="Global.asax.cs" Inherits="ASPNetBufferingWrapper.Global" Language="C#" %>
diff --git a/examples/targets/Configuration API/ASPNetBufferingWrapper/Global.asax.cs b/examples/targets/Configuration API/ASPNetBufferingWrapper/Global.asax.cs
new file mode 100644
index 0000000..b29df43
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetBufferingWrapper/Global.asax.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Web;
+using System.Web.Security;
+using System.Web.SessionState;
+using NLog.Targets.Wrappers;
+using NLog.Targets;
+using NLog.Config;
+using NLog;
+
+namespace ASPNetBufferingWrapper
+{
+ public class Global : System.Web.HttpApplication
+ {
+ protected void Application_Start(object sender, EventArgs e)
+ {
+ FileTarget fileTarget = new FileTarget();
+ fileTarget.FileName = "${basedir}/logfile.txt";
+
+ PostFilteringTargetWrapper postfilteringTarget = new PostFilteringTargetWrapper();
+ ASPNetBufferingTargetWrapper aspnetBufferingTarget = new ASPNetBufferingTargetWrapper();
+ aspnetBufferingTarget.WrappedTarget = postfilteringTarget;
+ postfilteringTarget.WrappedTarget = fileTarget;
+
+ postfilteringTarget.DefaultFilter = "level >= LogLevel.Info";
+ FilteringRule rule = new FilteringRule();
+ rule.Exists = "level >= LogLevel.Warn";
+ rule.Filter = "level >= LogLevel.Debug";
+ postfilteringTarget.Rules.Add(rule);
+
+ SimpleConfigurator.ConfigureForTargetLogging(aspnetBufferingTarget, LogLevel.Debug);
+ }
+
+ protected void Application_End(object sender, EventArgs e)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/targets/Configuration API/ASPNetBufferingWrapper/NormalPage.aspx b/examples/targets/Configuration API/ASPNetBufferingWrapper/NormalPage.aspx
new file mode 100644
index 0000000..857c5a9
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetBufferingWrapper/NormalPage.aspx
@@ -0,0 +1,16 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="NormalPage.aspx.cs" Inherits="ASPNetBufferingWrapper.NormalPage" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" >
+<head runat="server">
+ <title>Untitled Page</title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div>
+
+ </div>
+ </form>
+</body>
+</html>
diff --git a/examples/targets/Configuration API/ASPNetBufferingWrapper/NormalPage.aspx.cs b/examples/targets/Configuration API/ASPNetBufferingWrapper/NormalPage.aspx.cs
new file mode 100644
index 0000000..ff9de27
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetBufferingWrapper/NormalPage.aspx.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+namespace ASPNetBufferingWrapper
+{
+ public partial class NormalPage : System.Web.UI.Page
+ {
+ private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
+
+ protected void Page_Load(object sender, EventArgs e)
+ {
+ // This page simulates correct flow, no warnings are emitted
+ // This causes the postfiltering wrapper to emit only the Info messages
+
+ logger.Info("info1");
+ logger.Debug("some debug message");
+ logger.Debug("some other debug message");
+ logger.Debug("yet another other debug message");
+ logger.Info("info2");
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/ASPNetBufferingWrapper/NormalPage.aspx.designer.cs b/examples/targets/Configuration API/ASPNetBufferingWrapper/NormalPage.aspx.designer.cs
new file mode 100644
index 0000000..22aeca7
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetBufferingWrapper/NormalPage.aspx.designer.cs
@@ -0,0 +1,18 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace ASPNetBufferingWrapper
+{
+
+ public partial class NormalPage
+ {
+ protected System.Web.UI.HtmlControls.HtmlForm form1;
+ }
+}
diff --git a/examples/targets/Configuration API/ASPNetBufferingWrapper/PageWithWarnings.aspx b/examples/targets/Configuration API/ASPNetBufferingWrapper/PageWithWarnings.aspx
new file mode 100644
index 0000000..5c04e49
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetBufferingWrapper/PageWithWarnings.aspx
@@ -0,0 +1,16 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="PageWithWarnings.aspx.cs" Inherits="ASPNetBufferingWrapper.PageWithWarnings" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" >
+<head runat="server">
+ <title>Untitled Page</title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div>
+
+ </div>
+ </form>
+</body>
+</html>
diff --git a/examples/targets/Configuration API/ASPNetBufferingWrapper/PageWithWarnings.aspx.cs b/examples/targets/Configuration API/ASPNetBufferingWrapper/PageWithWarnings.aspx.cs
new file mode 100644
index 0000000..5e1122a
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetBufferingWrapper/PageWithWarnings.aspx.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+namespace ASPNetBufferingWrapper
+{
+ public partial class PageWithWarnings : System.Web.UI.Page
+ {
+ private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
+
+ protected void Page_Load(object sender, EventArgs e)
+ {
+ // This page simulates a page with some warning
+ // This causes the postfiltering wrapper to emit all the messages, including
+ // debug ones.
+
+ logger.Info("info1");
+ logger.Debug("some debug message");
+ logger.Debug("some other debug message");
+ logger.Debug("yet another other debug message");
+ logger.Warn("warning!");
+ logger.Info("info2");
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/ASPNetBufferingWrapper/PageWithWarnings.aspx.designer.cs b/examples/targets/Configuration API/ASPNetBufferingWrapper/PageWithWarnings.aspx.designer.cs
new file mode 100644
index 0000000..7966d16
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetBufferingWrapper/PageWithWarnings.aspx.designer.cs
@@ -0,0 +1,18 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace ASPNetBufferingWrapper
+{
+
+ public partial class PageWithWarnings
+ {
+ protected System.Web.UI.HtmlControls.HtmlForm form1;
+ }
+}
diff --git a/examples/targets/Configuration API/ASPNetBufferingWrapper/Properties/AssemblyInfo.cs b/examples/targets/Configuration API/ASPNetBufferingWrapper/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..5152314
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetBufferingWrapper/Properties/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("ASPNetBufferingWrapper")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: ComVisible(false)]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/examples/targets/Configuration API/ASPNetBufferingWrapper/Web.config b/examples/targets/Configuration API/ASPNetBufferingWrapper/Web.config
new file mode 100644
index 0000000..bceb39b
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetBufferingWrapper/Web.config
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+
+<configuration>
+
+ <appSettings/>
+ <connectionStrings/>
+
+ <system.web>
+ <compilation debug="true" />
+ <authentication mode="Windows" />
+ <trace enabled="true"/>
+
+ <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
+ <error statusCode="403" redirect="NoAccess.htm" />
+ <error statusCode="404" redirect="FileNotFound.htm" />
+ </customErrors>
+
+ <httpModules>
+ <add name="NLog" type="NLog.Web.NLogHttpModule, NLog"/>
+ </httpModules>
+ </system.web>
+</configuration>
diff --git a/examples/targets/Configuration API/ASPNetTrace/ASPNetTraceTest.csproj b/examples/targets/Configuration API/ASPNetTrace/ASPNetTraceTest.csproj
new file mode 100644
index 0000000..5e4c75b
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetTrace/ASPNetTraceTest.csproj
@@ -0,0 +1,130 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{C7BA2451-7027-4838-BD3B-02DC5DCD8CB5}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ApplicationIcon>
+ </ApplicationIcon>
+ <AssemblyKeyContainerName>
+ </AssemblyKeyContainerName>
+ <AssemblyName>ASPNetTraceTest</AssemblyName>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <DefaultClientScript>JScript</DefaultClientScript>
+ <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+ <DefaultTargetSchema>IE50</DefaultTargetSchema>
+ <DelaySign>false</DelaySign>
+ <OutputType>Library</OutputType>
+ <RootNamespace>ASPNetTraceTest</RootNamespace>
+ <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+ <StartupObject>
+ </StartupObject>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <OutputPath>bin\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>
+ </DefineConstants>
+ <DocumentationFile>
+ </DocumentationFile>
+ <DebugSymbols>true</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>
+ </NoWarn>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>1</WarningLevel>
+ <DebugType>full</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <OutputPath>bin\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>
+ </DefineConstants>
+ <DocumentationFile>
+ </DocumentationFile>
+ <DebugSymbols>false</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>
+ </NoWarn>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>1</WarningLevel>
+ <DebugType>none</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System">
+ <Name>System</Name>
+ </Reference>
+ <Reference Include="System.Data">
+ <Name>System.Data</Name>
+ </Reference>
+ <Reference Include="System.Drawing">
+ <Name>System.Drawing</Name>
+ </Reference>
+ <Reference Include="System.Web">
+ <Name>System.Web</Name>
+ </Reference>
+ <Reference Include="System.Xml">
+ <Name>System.Xml</Name>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="global.asax" />
+ <Content Include="test.aspx" />
+ <Content Include="web.config" />
+ <Compile Include="Global.asax.cs">
+ <DependentUpon>global.asax</DependentUpon>
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>
+ </PreBuildEvent>
+ <PostBuildEvent>
+ </PostBuildEvent>
+ </PropertyGroup>
+ <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v8.0\WebApplications\Microsoft.WebApplication.targets" />
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>False</UseIIS>
+ <AutoAssignPort>True</AutoAssignPort>
+ <DevelopmentServerPort>3698</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>
+ </IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/ASPNetTrace/ASPNetTraceTest.sln b/examples/targets/Configuration API/ASPNetTrace/ASPNetTraceTest.sln
new file mode 100644
index 0000000..0b99e0c
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetTrace/ASPNetTraceTest.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASPNetTraceTest", "ASPNetTraceTest.csproj", "{C7BA2451-7027-4838-BD3B-02DC5DCD8CB5}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C7BA2451-7027-4838-BD3B-02DC5DCD8CB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C7BA2451-7027-4838-BD3B-02DC5DCD8CB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C7BA2451-7027-4838-BD3B-02DC5DCD8CB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C7BA2451-7027-4838-BD3B-02DC5DCD8CB5}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/ASPNetTrace/Global.asax.cs b/examples/targets/Configuration API/ASPNetTrace/Global.asax.cs
new file mode 100644
index 0000000..116bfad
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetTrace/Global.asax.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Web;
+
+using NLog;
+using NLog.Targets;
+
+namespace SomeWebApplication
+{
+ public class Global : System.Web.HttpApplication
+ {
+ //
+ // this event handler is executed at the very start of the web application
+ // so this is a good place to configure targets programmatically
+ //
+ // alternative you could place this code in a static type constructor
+ //
+ protected void Application_Start(Object sender, EventArgs e)
+ {
+ ASPNetTraceTarget target = new ASPNetTraceTarget();
+ target.Layout = "${logger} ${message}";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/ASPNetTrace/README.txt b/examples/targets/Configuration API/ASPNetTrace/README.txt
new file mode 100644
index 0000000..902f3bb
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetTrace/README.txt
@@ -0,0 +1,4 @@
+To open this example in VS2005 you need to get
+"Visual Studio 2005 Web Application Projects" component available at:
+
+http://msdn.microsoft.com/asp.net/reference/infrastructure/wap/default.aspx
diff --git a/examples/targets/Configuration API/ASPNetTrace/global.asax b/examples/targets/Configuration API/ASPNetTrace/global.asax
new file mode 100644
index 0000000..f892077
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetTrace/global.asax
@@ -0,0 +1 @@
+<%@ Application Codebehind="Global.asax.cs" Inherits="SomeWebApplication.Global" %>
diff --git a/examples/targets/Configuration API/ASPNetTrace/test.aspx b/examples/targets/Configuration API/ASPNetTrace/test.aspx
new file mode 100644
index 0000000..a63aa3b
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetTrace/test.aspx
@@ -0,0 +1,23 @@
+<%@ Page language="c#" AutoEventWireup="true" %>
+<script language="C#" runat="server">
+NLog.Logger logger = NLog.LogManager.GetLogger("default.aspx");
+
+void Page_Load(Object sender, EventArgs e)
+{
+ logger.Info("got Page_Load() event");
+ logger.Warn("Some warning...");
+ logger.Error("Some error...");
+}
+</script>
+<html>
+<head>
+</head>
+<body>
+ <p>
+ Page has been loaded and log events have been registered for display in ASP.NET Trace facility.
+ </p>
+ <p>
+ <a href="Trace.axd">Click here to view trace output from Trace.axd</a>
+ </p>
+</body>
+</html>
diff --git a/examples/targets/Configuration API/ASPNetTrace/web.config b/examples/targets/Configuration API/ASPNetTrace/web.config
new file mode 100644
index 0000000..456e862
--- /dev/null
+++ b/examples/targets/Configuration API/ASPNetTrace/web.config
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<configuration>
+ <system.web>
+ <compilation defaultLanguage="c#" debug="true"/>
+ <!-- the following line enables ASP.NET trace -->
+ <trace enabled="true" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true"/>
+ <xhtmlConformance mode="Legacy"/></system.web>
+</configuration>
diff --git a/examples/targets/Configuration API/All_Targets.sln b/examples/targets/Configuration API/All_Targets.sln
new file mode 100644
index 0000000..6f701bb
--- /dev/null
+++ b/examples/targets/Configuration API/All_Targets.sln
@@ -0,0 +1,320 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsyncWrapper.Wrapping File", "AsyncWrapper\Wrapping File\AsyncWrapper.Wrapping File.csproj", "{29B2985C-C196-453F-848E-7195AADAC21C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chainsaw", "Chainsaw\Simple\Chainsaw.csproj", "{D7B11859-2A1B-49F7-A7C7-83B72495BF31}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColoredConsole.Row Highlighting", "ColoredConsole\Row Highlighting\ColoredConsole.Row Highlighting.csproj", "{71F8BD46-2468-4BD6-AE5D-7C81E56CF437}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColoredConsole", "ColoredConsole\Simple\ColoredConsole.csproj", "{695E7395-50BD-48BE-B1E2-7A4D21AF9F3D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColoredConsole.Word Highlighting", "ColoredConsole\Word Highlighting\ColoredConsole.Word Highlighting.csproj", "{72FEDAC3-072E-4966-AB1E-63E07F884321}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Console", "Console\Simple\Console.csproj", "{53FFA3C4-C63B-465C-AB3E-E4C3B0953AB1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Database.MSSQL", "Database\MSSQL\Database.MSSQL.csproj", "{4399886A-6016-4290-992E-1E77A14CEE46}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debug", "Debug\Simple\Debug.csproj", "{D0526912-F1E9-4D30-941F-3A229DCC9309}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger", "Debugger\Simple\Debugger.csproj", "{7720B322-2AFF-45C4-AF9A-EAB12BCFAFCE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventLog", "EventLog\Simple\EventLog.csproj", "{D7347273-CF36-4A75-B324-90D4644D9287}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File", "File\Simple\File.csproj", "{22DFBCFD-BDC3-4CD1-8DE5-E6872ACF7DB0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Asynchronous", "File\Asynchronous\File.Asynchronous.csproj", "{D26A09EB-2F43-4566-B304-81CF8055AD6B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Multiple2", "File\Multiple2\File.Multiple2.csproj", "{BE090500-80BA-45B8-A22F-114167DCF774}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Multiple", "File\Multiple\File.Multiple.csproj", "{45DC6DFF-4680-4739-8DD1-3EA91C1E2F19}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mail", "Mail\Simple\Mail.csproj", "{4132306C-EA25-4073-BFD5-BEBD9A88B600}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mail.Buffered", "Mail\Buffered\Mail.Buffered.csproj", "{4D14B05B-437D-4D83-A52E-526DEBF68999}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Memory", "Memory\Simple\Memory.csproj", "{4D71290B-65DC-4442-BE06-1CEBE07A26AC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessageBox", "MessageBox\Simple\MessageBox.csproj", "{26FC5FD6-F4E9-4E0F-BB0D-492AAE98D880}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSMQ", "MSMQ\Simple\MSMQ.csproj", "{5D70009B-698D-4A42-99F8-6C4CEE500AD8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSMQ.Multiple Queues", "MSMQ\Multiple Queues\MSMQ.Multiple Queues.csproj", "{18924A56-9ACA-4835-887B-3F8956DA7391}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Network", "Network\Simple\Network.csproj", "{1D3835B8-779E-4053-B03E-AC5292A48FF0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLogViewer", "NLogViewer\Simple\NLogViewer.csproj", "{36E8A9EF-C91F-443A-9FEF-B2AB27E3628A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Database.Oracle.Native", "Database\Oracle.Native\Database.Oracle.Native.csproj", "{0A94DFDE-A128-4F83-B0D2-2D97B18BF7BA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Database.Oracle.OleDb", "Database\Oracle.OleDb\Database.Oracle.OleDb.csproj", "{74641C69-189E-4F3E-B521-32BDC1121E5F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MethodCall", "MethodCall\Simple\MethodCall.csproj", "{8D851E55-9D32-4C20-A9CE-C1A35175D06E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Null", "Null\Simple\Null.csproj", "{D32BF09E-4214-42B3-AB66-C6CAE9C3CEB1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OutputDebugString", "OutputDebugString\Simple\OutputDebugString.csproj", "{670A30F5-4957-4E96-9677-71A2A40975BA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PerfCounter", "PerfCounter\Simple\PerfCounter.csproj", "{4C16C5D0-BB26-4639-8A2A-AEFCE8D3E5D6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Trace", "Trace\Simple\Trace.csproj", "{DE02AB34-33D1-42CA-A3F0-68F4B1BF98B1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebService", "WebService\Simple\WebService.csproj", "{70F18C83-2063-4D7F-96A9-4B1DA6752C95}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoFlushWrapper", "AutoFlushWrapper\Simple\AutoFlushWrapper.csproj", "{5B09A92A-9C6F-4EE2-B777-94281092DEDF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BufferingWrapper", "BufferingWrapper\Simple\BufferingWrapper.csproj", "{A516604C-19DE-4AED-9262-8F7271A42BFF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FallbackGroup", "FallbackGroup\Simple\FallbackGroup.csproj", "{08BA1481-13F1-4913-8BA6-EDE27AD01EE7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PostFilteringWrapper", "PostFilteringWrapper\Simple\PostFilteringWrapper.csproj", "{B259D6E2-5376-42C1-8D05-6107BA9D1B0C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RandomizeGroup", "RandomizeGroup\Simple\RandomizeGroup.csproj", "{DE1A0AAC-8832-429D-90D2-360C11ADA8CE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RepeatingWrapper", "RepeatingWrapper\Simple\RepeatingWrapper.csproj", "{F7F3F62B-96E4-4FB9-8923-FB883E87520F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RetryingWrapper", "RetryingWrapper\Simple\RetryingWrapper.csproj", "{B2529445-C84E-4E3F-B4D7-651E9C195D39}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RoundRobinGroup", "RoundRobinGroup\Simple\RoundRobinGroup.csproj", "{67EE6098-74A6-456F-8D27-C0D38D0A9B22}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SplitGroup", "SplitGroup\Simple\SplitGroup.csproj", "{6C8815D6-62F5-4DED-AE3F-0AF4D0178CDB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASPNetBufferingWrapper", "ASPNetBufferingWrapper\ASPNetBufferingWrapper.csproj", "{18041F69-4814-447B-B170-984E72423D4A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASPNetTraceTest", "ASPNetTrace\ASPNetTraceTest.csproj", "{C7BA2451-7027-4838-BD3B-02DC5DCD8CB5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FilteringWrapper", "FilteringWrapper\Simple\FilteringWrapper.csproj", "{BFEDB63A-1A05-4A51-B7C2-C59DE01BC617}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Archive1", "File\Archive1\File.Archive1.csproj", "{D8A33DCE-395C-4AD8-8FEC-74B8C8C74F53}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Archive2", "File\Archive2\File.Archive2.csproj", "{97DA6A8F-CF90-4E70-986E-E0A9D7196312}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Archive3", "File\Archive3\File.Archive3.csproj", "{400AFAB6-9354-49AB-A001-00B09235CEF1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Archive4", "File\Archive4\File.Archive4.csproj", "{F1BC69B4-E41C-4E72-AA57-FBF73663CAEB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FormControl", "FormControl\FormControl.csproj", "{20449142-40C3-4B1D-8F7C-2D3ED924FDA7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RichTextBox", "RichTextBox\Simple\RichTextBox.csproj", "{C6308AED-8472-4CCA-B49C-4AE9EBCE9DC8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RichTextBox.WordColoring", "RichTextBox\WordColoring\RichTextBox.WordColoring.csproj", "{7582650C-2D27-4AB1-9E2F-A93084A2AC79}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RichTextBox.RowColoring", "RichTextBox\RowColoring\RichTextBox.RowColoring.csproj", "{0D0CED51-E850-4107-81F8-910F234E0F81}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.CSV", "File\CSV\File.CSV.csproj", "{B55FBAF5-21E0-4375-8515-0FF9622D581E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {29B2985C-C196-453F-848E-7195AADAC21C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {29B2985C-C196-453F-848E-7195AADAC21C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {29B2985C-C196-453F-848E-7195AADAC21C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {29B2985C-C196-453F-848E-7195AADAC21C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D7B11859-2A1B-49F7-A7C7-83B72495BF31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D7B11859-2A1B-49F7-A7C7-83B72495BF31}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D7B11859-2A1B-49F7-A7C7-83B72495BF31}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D7B11859-2A1B-49F7-A7C7-83B72495BF31}.Release|Any CPU.Build.0 = Release|Any CPU
+ {71F8BD46-2468-4BD6-AE5D-7C81E56CF437}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {71F8BD46-2468-4BD6-AE5D-7C81E56CF437}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {71F8BD46-2468-4BD6-AE5D-7C81E56CF437}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {71F8BD46-2468-4BD6-AE5D-7C81E56CF437}.Release|Any CPU.Build.0 = Release|Any CPU
+ {695E7395-50BD-48BE-B1E2-7A4D21AF9F3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {695E7395-50BD-48BE-B1E2-7A4D21AF9F3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {695E7395-50BD-48BE-B1E2-7A4D21AF9F3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {695E7395-50BD-48BE-B1E2-7A4D21AF9F3D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {72FEDAC3-072E-4966-AB1E-63E07F884321}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {72FEDAC3-072E-4966-AB1E-63E07F884321}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {72FEDAC3-072E-4966-AB1E-63E07F884321}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {72FEDAC3-072E-4966-AB1E-63E07F884321}.Release|Any CPU.Build.0 = Release|Any CPU
+ {53FFA3C4-C63B-465C-AB3E-E4C3B0953AB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {53FFA3C4-C63B-465C-AB3E-E4C3B0953AB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {53FFA3C4-C63B-465C-AB3E-E4C3B0953AB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {53FFA3C4-C63B-465C-AB3E-E4C3B0953AB1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4399886A-6016-4290-992E-1E77A14CEE46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4399886A-6016-4290-992E-1E77A14CEE46}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4399886A-6016-4290-992E-1E77A14CEE46}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4399886A-6016-4290-992E-1E77A14CEE46}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D0526912-F1E9-4D30-941F-3A229DCC9309}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D0526912-F1E9-4D30-941F-3A229DCC9309}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D0526912-F1E9-4D30-941F-3A229DCC9309}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D0526912-F1E9-4D30-941F-3A229DCC9309}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7720B322-2AFF-45C4-AF9A-EAB12BCFAFCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7720B322-2AFF-45C4-AF9A-EAB12BCFAFCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7720B322-2AFF-45C4-AF9A-EAB12BCFAFCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7720B322-2AFF-45C4-AF9A-EAB12BCFAFCE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D7347273-CF36-4A75-B324-90D4644D9287}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D7347273-CF36-4A75-B324-90D4644D9287}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D7347273-CF36-4A75-B324-90D4644D9287}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D7347273-CF36-4A75-B324-90D4644D9287}.Release|Any CPU.Build.0 = Release|Any CPU
+ {22DFBCFD-BDC3-4CD1-8DE5-E6872ACF7DB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {22DFBCFD-BDC3-4CD1-8DE5-E6872ACF7DB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {22DFBCFD-BDC3-4CD1-8DE5-E6872ACF7DB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {22DFBCFD-BDC3-4CD1-8DE5-E6872ACF7DB0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D26A09EB-2F43-4566-B304-81CF8055AD6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D26A09EB-2F43-4566-B304-81CF8055AD6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D26A09EB-2F43-4566-B304-81CF8055AD6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D26A09EB-2F43-4566-B304-81CF8055AD6B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BE090500-80BA-45B8-A22F-114167DCF774}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BE090500-80BA-45B8-A22F-114167DCF774}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BE090500-80BA-45B8-A22F-114167DCF774}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BE090500-80BA-45B8-A22F-114167DCF774}.Release|Any CPU.Build.0 = Release|Any CPU
+ {45DC6DFF-4680-4739-8DD1-3EA91C1E2F19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {45DC6DFF-4680-4739-8DD1-3EA91C1E2F19}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {45DC6DFF-4680-4739-8DD1-3EA91C1E2F19}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {45DC6DFF-4680-4739-8DD1-3EA91C1E2F19}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4132306C-EA25-4073-BFD5-BEBD9A88B600}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4132306C-EA25-4073-BFD5-BEBD9A88B600}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4132306C-EA25-4073-BFD5-BEBD9A88B600}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4132306C-EA25-4073-BFD5-BEBD9A88B600}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4D14B05B-437D-4D83-A52E-526DEBF68999}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4D14B05B-437D-4D83-A52E-526DEBF68999}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4D14B05B-437D-4D83-A52E-526DEBF68999}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4D14B05B-437D-4D83-A52E-526DEBF68999}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4D71290B-65DC-4442-BE06-1CEBE07A26AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4D71290B-65DC-4442-BE06-1CEBE07A26AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4D71290B-65DC-4442-BE06-1CEBE07A26AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4D71290B-65DC-4442-BE06-1CEBE07A26AC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {26FC5FD6-F4E9-4E0F-BB0D-492AAE98D880}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {26FC5FD6-F4E9-4E0F-BB0D-492AAE98D880}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {26FC5FD6-F4E9-4E0F-BB0D-492AAE98D880}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {26FC5FD6-F4E9-4E0F-BB0D-492AAE98D880}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5D70009B-698D-4A42-99F8-6C4CEE500AD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5D70009B-698D-4A42-99F8-6C4CEE500AD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5D70009B-698D-4A42-99F8-6C4CEE500AD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5D70009B-698D-4A42-99F8-6C4CEE500AD8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {18924A56-9ACA-4835-887B-3F8956DA7391}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {18924A56-9ACA-4835-887B-3F8956DA7391}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {18924A56-9ACA-4835-887B-3F8956DA7391}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {18924A56-9ACA-4835-887B-3F8956DA7391}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1D3835B8-779E-4053-B03E-AC5292A48FF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1D3835B8-779E-4053-B03E-AC5292A48FF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1D3835B8-779E-4053-B03E-AC5292A48FF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1D3835B8-779E-4053-B03E-AC5292A48FF0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {36E8A9EF-C91F-443A-9FEF-B2AB27E3628A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {36E8A9EF-C91F-443A-9FEF-B2AB27E3628A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {36E8A9EF-C91F-443A-9FEF-B2AB27E3628A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {36E8A9EF-C91F-443A-9FEF-B2AB27E3628A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0A94DFDE-A128-4F83-B0D2-2D97B18BF7BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0A94DFDE-A128-4F83-B0D2-2D97B18BF7BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0A94DFDE-A128-4F83-B0D2-2D97B18BF7BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0A94DFDE-A128-4F83-B0D2-2D97B18BF7BA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {74641C69-189E-4F3E-B521-32BDC1121E5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {74641C69-189E-4F3E-B521-32BDC1121E5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {74641C69-189E-4F3E-B521-32BDC1121E5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {74641C69-189E-4F3E-B521-32BDC1121E5F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8D851E55-9D32-4C20-A9CE-C1A35175D06E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8D851E55-9D32-4C20-A9CE-C1A35175D06E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8D851E55-9D32-4C20-A9CE-C1A35175D06E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8D851E55-9D32-4C20-A9CE-C1A35175D06E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D32BF09E-4214-42B3-AB66-C6CAE9C3CEB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D32BF09E-4214-42B3-AB66-C6CAE9C3CEB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D32BF09E-4214-42B3-AB66-C6CAE9C3CEB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D32BF09E-4214-42B3-AB66-C6CAE9C3CEB1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {670A30F5-4957-4E96-9677-71A2A40975BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {670A30F5-4957-4E96-9677-71A2A40975BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {670A30F5-4957-4E96-9677-71A2A40975BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {670A30F5-4957-4E96-9677-71A2A40975BA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4C16C5D0-BB26-4639-8A2A-AEFCE8D3E5D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4C16C5D0-BB26-4639-8A2A-AEFCE8D3E5D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4C16C5D0-BB26-4639-8A2A-AEFCE8D3E5D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4C16C5D0-BB26-4639-8A2A-AEFCE8D3E5D6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DE02AB34-33D1-42CA-A3F0-68F4B1BF98B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DE02AB34-33D1-42CA-A3F0-68F4B1BF98B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DE02AB34-33D1-42CA-A3F0-68F4B1BF98B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DE02AB34-33D1-42CA-A3F0-68F4B1BF98B1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {70F18C83-2063-4D7F-96A9-4B1DA6752C95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {70F18C83-2063-4D7F-96A9-4B1DA6752C95}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {70F18C83-2063-4D7F-96A9-4B1DA6752C95}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {70F18C83-2063-4D7F-96A9-4B1DA6752C95}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5B09A92A-9C6F-4EE2-B777-94281092DEDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5B09A92A-9C6F-4EE2-B777-94281092DEDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5B09A92A-9C6F-4EE2-B777-94281092DEDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5B09A92A-9C6F-4EE2-B777-94281092DEDF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A516604C-19DE-4AED-9262-8F7271A42BFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A516604C-19DE-4AED-9262-8F7271A42BFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A516604C-19DE-4AED-9262-8F7271A42BFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A516604C-19DE-4AED-9262-8F7271A42BFF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {08BA1481-13F1-4913-8BA6-EDE27AD01EE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {08BA1481-13F1-4913-8BA6-EDE27AD01EE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {08BA1481-13F1-4913-8BA6-EDE27AD01EE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {08BA1481-13F1-4913-8BA6-EDE27AD01EE7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B259D6E2-5376-42C1-8D05-6107BA9D1B0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B259D6E2-5376-42C1-8D05-6107BA9D1B0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B259D6E2-5376-42C1-8D05-6107BA9D1B0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B259D6E2-5376-42C1-8D05-6107BA9D1B0C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DE1A0AAC-8832-429D-90D2-360C11ADA8CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DE1A0AAC-8832-429D-90D2-360C11ADA8CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DE1A0AAC-8832-429D-90D2-360C11ADA8CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DE1A0AAC-8832-429D-90D2-360C11ADA8CE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F7F3F62B-96E4-4FB9-8923-FB883E87520F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F7F3F62B-96E4-4FB9-8923-FB883E87520F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F7F3F62B-96E4-4FB9-8923-FB883E87520F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F7F3F62B-96E4-4FB9-8923-FB883E87520F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B2529445-C84E-4E3F-B4D7-651E9C195D39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B2529445-C84E-4E3F-B4D7-651E9C195D39}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B2529445-C84E-4E3F-B4D7-651E9C195D39}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B2529445-C84E-4E3F-B4D7-651E9C195D39}.Release|Any CPU.Build.0 = Release|Any CPU
+ {67EE6098-74A6-456F-8D27-C0D38D0A9B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {67EE6098-74A6-456F-8D27-C0D38D0A9B22}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {67EE6098-74A6-456F-8D27-C0D38D0A9B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {67EE6098-74A6-456F-8D27-C0D38D0A9B22}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6C8815D6-62F5-4DED-AE3F-0AF4D0178CDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6C8815D6-62F5-4DED-AE3F-0AF4D0178CDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6C8815D6-62F5-4DED-AE3F-0AF4D0178CDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6C8815D6-62F5-4DED-AE3F-0AF4D0178CDB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {18041F69-4814-447B-B170-984E72423D4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {18041F69-4814-447B-B170-984E72423D4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {18041F69-4814-447B-B170-984E72423D4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {18041F69-4814-447B-B170-984E72423D4A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C7BA2451-7027-4838-BD3B-02DC5DCD8CB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C7BA2451-7027-4838-BD3B-02DC5DCD8CB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C7BA2451-7027-4838-BD3B-02DC5DCD8CB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C7BA2451-7027-4838-BD3B-02DC5DCD8CB5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BFEDB63A-1A05-4A51-B7C2-C59DE01BC617}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BFEDB63A-1A05-4A51-B7C2-C59DE01BC617}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BFEDB63A-1A05-4A51-B7C2-C59DE01BC617}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BFEDB63A-1A05-4A51-B7C2-C59DE01BC617}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D8A33DCE-395C-4AD8-8FEC-74B8C8C74F53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D8A33DCE-395C-4AD8-8FEC-74B8C8C74F53}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D8A33DCE-395C-4AD8-8FEC-74B8C8C74F53}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D8A33DCE-395C-4AD8-8FEC-74B8C8C74F53}.Release|Any CPU.Build.0 = Release|Any CPU
+ {97DA6A8F-CF90-4E70-986E-E0A9D7196312}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {97DA6A8F-CF90-4E70-986E-E0A9D7196312}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {97DA6A8F-CF90-4E70-986E-E0A9D7196312}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {97DA6A8F-CF90-4E70-986E-E0A9D7196312}.Release|Any CPU.Build.0 = Release|Any CPU
+ {400AFAB6-9354-49AB-A001-00B09235CEF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {400AFAB6-9354-49AB-A001-00B09235CEF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {400AFAB6-9354-49AB-A001-00B09235CEF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {400AFAB6-9354-49AB-A001-00B09235CEF1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F1BC69B4-E41C-4E72-AA57-FBF73663CAEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F1BC69B4-E41C-4E72-AA57-FBF73663CAEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F1BC69B4-E41C-4E72-AA57-FBF73663CAEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F1BC69B4-E41C-4E72-AA57-FBF73663CAEB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C6308AED-8472-4CCA-B49C-4AE9EBCE9DC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C6308AED-8472-4CCA-B49C-4AE9EBCE9DC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C6308AED-8472-4CCA-B49C-4AE9EBCE9DC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C6308AED-8472-4CCA-B49C-4AE9EBCE9DC8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7582650C-2D27-4AB1-9E2F-A93084A2AC79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7582650C-2D27-4AB1-9E2F-A93084A2AC79}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7582650C-2D27-4AB1-9E2F-A93084A2AC79}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7582650C-2D27-4AB1-9E2F-A93084A2AC79}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0D0CED51-E850-4107-81F8-910F234E0F81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0D0CED51-E850-4107-81F8-910F234E0F81}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0D0CED51-E850-4107-81F8-910F234E0F81}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0D0CED51-E850-4107-81F8-910F234E0F81}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B55FBAF5-21E0-4375-8515-0FF9622D581E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B55FBAF5-21E0-4375-8515-0FF9622D581E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B55FBAF5-21E0-4375-8515-0FF9622D581E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B55FBAF5-21E0-4375-8515-0FF9622D581E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/AsyncWrapper/Wrapping File/AsyncWrapper.Wrapping File.csproj b/examples/targets/Configuration API/AsyncWrapper/Wrapping File/AsyncWrapper.Wrapping File.csproj
new file mode 100644
index 0000000..0063ad7
--- /dev/null
+++ b/examples/targets/Configuration API/AsyncWrapper/Wrapping File/AsyncWrapper.Wrapping File.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{29B2985C-C196-453F-848E-7195AADAC21C}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>AsyncWrapper.Wrapping File</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/AsyncWrapper/Wrapping File/AsyncWrapper.Wrapping File.sln b/examples/targets/Configuration API/AsyncWrapper/Wrapping File/AsyncWrapper.Wrapping File.sln
new file mode 100644
index 0000000..f123611
--- /dev/null
+++ b/examples/targets/Configuration API/AsyncWrapper/Wrapping File/AsyncWrapper.Wrapping File.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsyncWrapper.Wrapping File", "AsyncWrapper.Wrapping File.csproj", "{29B2985C-C196-453F-848E-7195AADAC21C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {29B2985C-C196-453F-848E-7195AADAC21C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {29B2985C-C196-453F-848E-7195AADAC21C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {29B2985C-C196-453F-848E-7195AADAC21C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {29B2985C-C196-453F-848E-7195AADAC21C}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/AsyncWrapper/Wrapping File/Example.cs b/examples/targets/Configuration API/AsyncWrapper/Wrapping File/Example.cs
new file mode 100644
index 0000000..e5ac1ec
--- /dev/null
+++ b/examples/targets/Configuration API/AsyncWrapper/Wrapping File/Example.cs
@@ -0,0 +1,27 @@
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget target = new FileTarget();
+ target.Layout = "${longdate} ${logger} ${message}";
+ target.FileName = "${basedir}/logs/logfile.txt";
+ target.KeepFileOpen = false;
+ target.Encoding = "iso-8859-2";
+
+ AsyncTargetWrapper wrapper = new AsyncTargetWrapper();
+ wrapper.WrappedTarget = target;
+ wrapper.QueueLimit = 5000;
+ wrapper.OverflowAction = AsyncTargetWrapperOverflowAction.Discard;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(wrapper, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+
+ wrapper.Flush();
+ }
+}
diff --git a/examples/targets/Configuration API/AutoFlushWrapper/Simple/AutoFlushWrapper.csproj b/examples/targets/Configuration API/AutoFlushWrapper/Simple/AutoFlushWrapper.csproj
new file mode 100644
index 0000000..365ef9c
--- /dev/null
+++ b/examples/targets/Configuration API/AutoFlushWrapper/Simple/AutoFlushWrapper.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{5B09A92A-9C6F-4EE2-B777-94281092DEDF}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>AutoFlushWrapper</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/AutoFlushWrapper/Simple/AutoFlushWrapper.sln b/examples/targets/Configuration API/AutoFlushWrapper/Simple/AutoFlushWrapper.sln
new file mode 100644
index 0000000..24c9eed
--- /dev/null
+++ b/examples/targets/Configuration API/AutoFlushWrapper/Simple/AutoFlushWrapper.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoFlushWrapper", "AutoFlushWrapper.csproj", "{5B09A92A-9C6F-4EE2-B777-94281092DEDF}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5B09A92A-9C6F-4EE2-B777-94281092DEDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5B09A92A-9C6F-4EE2-B777-94281092DEDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5B09A92A-9C6F-4EE2-B777-94281092DEDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5B09A92A-9C6F-4EE2-B777-94281092DEDF}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/AutoFlushWrapper/Simple/Example.cs b/examples/targets/Configuration API/AutoFlushWrapper/Simple/Example.cs
new file mode 100644
index 0000000..b58e1a2
--- /dev/null
+++ b/examples/targets/Configuration API/AutoFlushWrapper/Simple/Example.cs
@@ -0,0 +1,23 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+using System.Diagnostics;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget wrappedTarget = new FileTarget();
+ wrappedTarget.FileName = "${basedir}/file.txt";
+
+ AutoFlushTargetWrapper target = new AutoFlushTargetWrapper();
+ target.WrappedTarget = wrappedTarget;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/BufferingWrapper/Simple/BufferingWrapper.csproj b/examples/targets/Configuration API/BufferingWrapper/Simple/BufferingWrapper.csproj
new file mode 100644
index 0000000..f4914dc
--- /dev/null
+++ b/examples/targets/Configuration API/BufferingWrapper/Simple/BufferingWrapper.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{A516604C-19DE-4AED-9262-8F7271A42BFF}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>BufferingWrapper</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/BufferingWrapper/Simple/BufferingWrapper.sln b/examples/targets/Configuration API/BufferingWrapper/Simple/BufferingWrapper.sln
new file mode 100644
index 0000000..480fa1a
--- /dev/null
+++ b/examples/targets/Configuration API/BufferingWrapper/Simple/BufferingWrapper.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BufferingWrapper", "BufferingWrapper.csproj", "{A516604C-19DE-4AED-9262-8F7271A42BFF}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A516604C-19DE-4AED-9262-8F7271A42BFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A516604C-19DE-4AED-9262-8F7271A42BFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A516604C-19DE-4AED-9262-8F7271A42BFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A516604C-19DE-4AED-9262-8F7271A42BFF}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/BufferingWrapper/Simple/Example.cs b/examples/targets/Configuration API/BufferingWrapper/Simple/Example.cs
new file mode 100644
index 0000000..8c8184f
--- /dev/null
+++ b/examples/targets/Configuration API/BufferingWrapper/Simple/Example.cs
@@ -0,0 +1,24 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+using System.Diagnostics;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget wrappedTarget = new FileTarget();
+ wrappedTarget.FileName = "${basedir}/file.txt";
+
+ BufferingTargetWrapper target = new BufferingTargetWrapper();
+ target.BufferSize = 100;
+ target.WrappedTarget = wrappedTarget;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/Chainsaw/Simple/Chainsaw.csproj b/examples/targets/Configuration API/Chainsaw/Simple/Chainsaw.csproj
new file mode 100644
index 0000000..97aeab6
--- /dev/null
+++ b/examples/targets/Configuration API/Chainsaw/Simple/Chainsaw.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{D7B11859-2A1B-49F7-A7C7-83B72495BF31}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Chainsaw</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/Chainsaw/Simple/Chainsaw.sln b/examples/targets/Configuration API/Chainsaw/Simple/Chainsaw.sln
new file mode 100644
index 0000000..9d07a3c
--- /dev/null
+++ b/examples/targets/Configuration API/Chainsaw/Simple/Chainsaw.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chainsaw", "Chainsaw.csproj", "{D7B11859-2A1B-49F7-A7C7-83B72495BF31}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D7B11859-2A1B-49F7-A7C7-83B72495BF31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D7B11859-2A1B-49F7-A7C7-83B72495BF31}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D7B11859-2A1B-49F7-A7C7-83B72495BF31}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D7B11859-2A1B-49F7-A7C7-83B72495BF31}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Chainsaw/Simple/Example.cs b/examples/targets/Configuration API/Chainsaw/Simple/Example.cs
new file mode 100644
index 0000000..ed1a188
--- /dev/null
+++ b/examples/targets/Configuration API/Chainsaw/Simple/Example.cs
@@ -0,0 +1,21 @@
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ ChainsawTarget target = new ChainsawTarget();
+ target.Address = "udp://localhost:4000";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Trace("log message 1");
+ logger.Debug("log message 2");
+ logger.Info("log message 3");
+ logger.Warn("log message 4");
+ logger.Error("log message 5");
+ logger.Fatal("log message 6");
+ }
+}
diff --git a/examples/targets/Configuration API/ColoredConsole/Row Highlighting/ColoredConsole.Row Highlighting.csproj b/examples/targets/Configuration API/ColoredConsole/Row Highlighting/ColoredConsole.Row Highlighting.csproj
new file mode 100644
index 0000000..ef39aa2
--- /dev/null
+++ b/examples/targets/Configuration API/ColoredConsole/Row Highlighting/ColoredConsole.Row Highlighting.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{71F8BD46-2468-4BD6-AE5D-7C81E56CF437}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>ColoredConsole.Row Highlighting</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/ColoredConsole/Row Highlighting/ColoredConsole.Row Highlighting.sln b/examples/targets/Configuration API/ColoredConsole/Row Highlighting/ColoredConsole.Row Highlighting.sln
new file mode 100644
index 0000000..56d7132
--- /dev/null
+++ b/examples/targets/Configuration API/ColoredConsole/Row Highlighting/ColoredConsole.Row Highlighting.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColoredConsole.Row Highlighting", "ColoredConsole.Row Highlighting.csproj", "{71F8BD46-2468-4BD6-AE5D-7C81E56CF437}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {71F8BD46-2468-4BD6-AE5D-7C81E56CF437}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {71F8BD46-2468-4BD6-AE5D-7C81E56CF437}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {71F8BD46-2468-4BD6-AE5D-7C81E56CF437}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {71F8BD46-2468-4BD6-AE5D-7C81E56CF437}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/ColoredConsole/Row Highlighting/Example.cs b/examples/targets/Configuration API/ColoredConsole/Row Highlighting/Example.cs
new file mode 100644
index 0000000..fb2f749
--- /dev/null
+++ b/examples/targets/Configuration API/ColoredConsole/Row Highlighting/Example.cs
@@ -0,0 +1,44 @@
+using NLog;
+using NLog.Win32.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ ColoredConsoleTarget target = new ColoredConsoleTarget();
+ target.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
+ target.RowHighlightingRules.Add(
+ new ConsoleRowHighlightingRule(
+ "level >= LogLevel.Error and contains(message,'serious')", // condition
+ ConsoleOutputColor.White, // foreground color
+ ConsoleOutputColor.Red // background color
+ )
+ );
+
+ target.RowHighlightingRules.Add(
+ new ConsoleRowHighlightingRule(
+ "starts-with(logger,'Example')", // condition
+ ConsoleOutputColor.Yellow, // foreground color
+ ConsoleOutputColor.DarkBlue) // background color
+ );
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Trace);
+
+ // LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration("ColoredConsoleTargetRowHighlighting.nlog");
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Trace("trace log message");
+ logger.Debug("debug log message");
+ logger.Info("info log message");
+ logger.Warn("warn log message");
+ logger.Error("very serious error log message");
+ logger.Fatal("fatal log message, rather serious");
+
+ Logger logger2 = LogManager.GetLogger("Another");
+ logger2.Trace("trace log message");
+ logger2.Debug("debug log message");
+ logger2.Info("info log message");
+ logger2.Warn("warn log message");
+ logger2.Error("very serious error log message");
+ logger2.Fatal("fatal log message");
+ }
+}
diff --git a/examples/targets/Configuration API/ColoredConsole/Simple/ColoredConsole.csproj b/examples/targets/Configuration API/ColoredConsole/Simple/ColoredConsole.csproj
new file mode 100644
index 0000000..fdab1af
--- /dev/null
+++ b/examples/targets/Configuration API/ColoredConsole/Simple/ColoredConsole.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{695E7395-50BD-48BE-B1E2-7A4D21AF9F3D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>ColoredConsole</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/ColoredConsole/Simple/ColoredConsole.sln b/examples/targets/Configuration API/ColoredConsole/Simple/ColoredConsole.sln
new file mode 100644
index 0000000..c9e5e87
--- /dev/null
+++ b/examples/targets/Configuration API/ColoredConsole/Simple/ColoredConsole.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColoredConsole", "ColoredConsole.csproj", "{695E7395-50BD-48BE-B1E2-7A4D21AF9F3D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {695E7395-50BD-48BE-B1E2-7A4D21AF9F3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {695E7395-50BD-48BE-B1E2-7A4D21AF9F3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {695E7395-50BD-48BE-B1E2-7A4D21AF9F3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {695E7395-50BD-48BE-B1E2-7A4D21AF9F3D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/ColoredConsole/Simple/Example.cs b/examples/targets/Configuration API/ColoredConsole/Simple/Example.cs
new file mode 100644
index 0000000..1b5b774
--- /dev/null
+++ b/examples/targets/Configuration API/ColoredConsole/Simple/Example.cs
@@ -0,0 +1,21 @@
+using NLog;
+using NLog.Win32.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ ColoredConsoleTarget target = new ColoredConsoleTarget();
+ target.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Trace);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Trace("trace log message");
+ logger.Debug("debug log message");
+ logger.Info("info log message");
+ logger.Warn("warn log message");
+ logger.Error("error log message");
+ logger.Fatal("fatal log message");
+ }
+}
diff --git a/examples/targets/Configuration API/ColoredConsole/Word Highlighting/ColoredConsole.Word Highlighting.csproj b/examples/targets/Configuration API/ColoredConsole/Word Highlighting/ColoredConsole.Word Highlighting.csproj
new file mode 100644
index 0000000..4c0471e
--- /dev/null
+++ b/examples/targets/Configuration API/ColoredConsole/Word Highlighting/ColoredConsole.Word Highlighting.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{72FEDAC3-072E-4966-AB1E-63E07F884321}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>ColoredConsole.Word Highlighting</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/ColoredConsole/Word Highlighting/ColoredConsole.Word Highlighting.sln b/examples/targets/Configuration API/ColoredConsole/Word Highlighting/ColoredConsole.Word Highlighting.sln
new file mode 100644
index 0000000..54512ef
--- /dev/null
+++ b/examples/targets/Configuration API/ColoredConsole/Word Highlighting/ColoredConsole.Word Highlighting.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColoredConsole.Word Highlighting", "ColoredConsole.Word Highlighting.csproj", "{72FEDAC3-072E-4966-AB1E-63E07F884321}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {72FEDAC3-072E-4966-AB1E-63E07F884321}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {72FEDAC3-072E-4966-AB1E-63E07F884321}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {72FEDAC3-072E-4966-AB1E-63E07F884321}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {72FEDAC3-072E-4966-AB1E-63E07F884321}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/ColoredConsole/Word Highlighting/Example.cs b/examples/targets/Configuration API/ColoredConsole/Word Highlighting/Example.cs
new file mode 100644
index 0000000..8f8a207
--- /dev/null
+++ b/examples/targets/Configuration API/ColoredConsole/Word Highlighting/Example.cs
@@ -0,0 +1,30 @@
+using NLog;
+using NLog.Win32.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ ColoredConsoleTarget target = new ColoredConsoleTarget();
+ target.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
+ target.WordHighlightingRules.Add(
+ new ConsoleWordHighlightingRule("log",
+ ConsoleOutputColor.NoChange,
+ ConsoleOutputColor.DarkGreen));
+ target.WordHighlightingRules.Add(
+ new ConsoleWordHighlightingRule("abc",
+ ConsoleOutputColor.Cyan,
+ ConsoleOutputColor.NoChange));
+
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Trace);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Trace("trace log message abcdefghijklmnopq");
+ logger.Debug("debug log message");
+ logger.Info("info log message abc abcdefghijklmnopq");
+ logger.Warn("warn log message");
+ logger.Error("error log abcdefghijklmnopq message abc");
+ logger.Fatal("fatal log message abcdefghijklmnopq abc");
+ }
+}
diff --git a/examples/targets/Configuration API/Console/Simple/Console.csproj b/examples/targets/Configuration API/Console/Simple/Console.csproj
new file mode 100644
index 0000000..da18060
--- /dev/null
+++ b/examples/targets/Configuration API/Console/Simple/Console.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{53FFA3C4-C63B-465C-AB3E-E4C3B0953AB1}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Console</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/Console/Simple/Console.sln b/examples/targets/Configuration API/Console/Simple/Console.sln
new file mode 100644
index 0000000..45a1dda
--- /dev/null
+++ b/examples/targets/Configuration API/Console/Simple/Console.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Console", "Console.csproj", "{53FFA3C4-C63B-465C-AB3E-E4C3B0953AB1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {53FFA3C4-C63B-465C-AB3E-E4C3B0953AB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {53FFA3C4-C63B-465C-AB3E-E4C3B0953AB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {53FFA3C4-C63B-465C-AB3E-E4C3B0953AB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {53FFA3C4-C63B-465C-AB3E-E4C3B0953AB1}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Console/Simple/Example.cs b/examples/targets/Configuration API/Console/Simple/Example.cs
new file mode 100644
index 0000000..b681bc2
--- /dev/null
+++ b/examples/targets/Configuration API/Console/Simple/Example.cs
@@ -0,0 +1,16 @@
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ ConsoleTarget target = new ConsoleTarget();
+ target.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/Database/MSSQL/Database.MSSQL.csproj b/examples/targets/Configuration API/Database/MSSQL/Database.MSSQL.csproj
new file mode 100644
index 0000000..faffe64
--- /dev/null
+++ b/examples/targets/Configuration API/Database/MSSQL/Database.MSSQL.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{4399886A-6016-4290-992E-1E77A14CEE46}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Database.MSSQL</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/Database/MSSQL/Database.MSSQL.sln b/examples/targets/Configuration API/Database/MSSQL/Database.MSSQL.sln
new file mode 100644
index 0000000..0f4e3b2
--- /dev/null
+++ b/examples/targets/Configuration API/Database/MSSQL/Database.MSSQL.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Database.MSSQL", "Database.MSSQL.csproj", "{4399886A-6016-4290-992E-1E77A14CEE46}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4399886A-6016-4290-992E-1E77A14CEE46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4399886A-6016-4290-992E-1E77A14CEE46}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4399886A-6016-4290-992E-1E77A14CEE46}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4399886A-6016-4290-992E-1E77A14CEE46}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Database/MSSQL/Example.cs b/examples/targets/Configuration API/Database/MSSQL/Example.cs
new file mode 100644
index 0000000..c2fdbd6
--- /dev/null
+++ b/examples/targets/Configuration API/Database/MSSQL/Example.cs
@@ -0,0 +1,43 @@
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ DatabaseTarget target = new DatabaseTarget();
+ DatabaseParameterInfo param;
+
+ target.DBProvider = "mssql";
+ target.DBHost = ".";
+ target.DBUserName = "nloguser";
+ target.DBPassword = "pass";
+ target.DBDatabase = "databasename";
+ target.CommandText = "insert into LogTable(time_stamp,level,logger,message) values(@time_stamp, @level, @logger, @message);";
+
+ param = new DatabaseParameterInfo();
+ param.Name = "@time_stamp";
+ param.Layout = "${date}";
+ target.Parameters.Add(param);
+
+ param = new DatabaseParameterInfo();
+ param.Name = "@level";
+ param.Layout = "${level}";
+ target.Parameters.Add(param);
+
+ param = new DatabaseParameterInfo();
+ param.Name = "@logger";
+ param.Layout = "${logger}";
+ target.Parameters.Add(param);
+
+ param = new DatabaseParameterInfo();
+ param.Name = "@message";
+ param.Layout = "${message}";
+ target.Parameters.Add(param);
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/Database/Oracle.Native/Database.Oracle.Native.csproj b/examples/targets/Configuration API/Database/Oracle.Native/Database.Oracle.Native.csproj
new file mode 100644
index 0000000..52abc93
--- /dev/null
+++ b/examples/targets/Configuration API/Database/Oracle.Native/Database.Oracle.Native.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{0A94DFDE-A128-4F83-B0D2-2D97B18BF7BA}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Database.Oracle.Native</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/Database/Oracle.Native/Database.Oracle.Native.sln b/examples/targets/Configuration API/Database/Oracle.Native/Database.Oracle.Native.sln
new file mode 100644
index 0000000..72afa6f
--- /dev/null
+++ b/examples/targets/Configuration API/Database/Oracle.Native/Database.Oracle.Native.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Database.Oracle.Native", "Database.Oracle.Native.csproj", "{0A94DFDE-A128-4F83-B0D2-2D97B18BF7BA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0A94DFDE-A128-4F83-B0D2-2D97B18BF7BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0A94DFDE-A128-4F83-B0D2-2D97B18BF7BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0A94DFDE-A128-4F83-B0D2-2D97B18BF7BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0A94DFDE-A128-4F83-B0D2-2D97B18BF7BA}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Database/Oracle.Native/Example.cs b/examples/targets/Configuration API/Database/Oracle.Native/Example.cs
new file mode 100644
index 0000000..43b6c7e
--- /dev/null
+++ b/examples/targets/Configuration API/Database/Oracle.Native/Example.cs
@@ -0,0 +1,28 @@
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ DatabaseTarget target = new DatabaseTarget();
+ DatabaseParameterInfo param;
+
+ target.DBProvider = "System.Data.OracleClient.OracleConnection,System.Data.OracleClient, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
+ target.ConnectionString = "Data Source=MYORACLEDB;User Id=DBO;Password=MYPASSWORD;Integrated Security=no;";
+ target.CommandText = "insert into LOGTABLE( TIME_STAMP,LOGLEVEL,LOGGER,CALLSITE,MESSAGE) values( :TIME_STAMP,:LOGLEVEL,:LOGGER,:CALLSITE,:MESSAGE)";
+
+ target.KeepConnection = true;
+
+ target.Parameters.Add(new DatabaseParameterInfo("TIME_STAMP", "${longdate}"));
+ target.Parameters.Add(new DatabaseParameterInfo("LOGLEVEL", "${level:uppercase=true}"));
+ target.Parameters.Add(new DatabaseParameterInfo("LOGGER", "${logger}"));
+ target.Parameters.Add(new DatabaseParameterInfo("CALLSITE", "${callsite:filename=true}"));
+ target.Parameters.Add(new DatabaseParameterInfo("MESSAGE", "${message}"));
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/Database/Oracle.OleDb/Database.Oracle.OleDb.csproj b/examples/targets/Configuration API/Database/Oracle.OleDb/Database.Oracle.OleDb.csproj
new file mode 100644
index 0000000..27f2ecd
--- /dev/null
+++ b/examples/targets/Configuration API/Database/Oracle.OleDb/Database.Oracle.OleDb.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{74641C69-189E-4F3E-B521-32BDC1121E5F}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Database.Oracle.OleDb</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/Database/Oracle.OleDb/Database.Oracle.OleDb.sln b/examples/targets/Configuration API/Database/Oracle.OleDb/Database.Oracle.OleDb.sln
new file mode 100644
index 0000000..97bf8ac
--- /dev/null
+++ b/examples/targets/Configuration API/Database/Oracle.OleDb/Database.Oracle.OleDb.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Database.Oracle.OleDb", "Database.Oracle.OleDb.csproj", "{74641C69-189E-4F3E-B521-32BDC1121E5F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {74641C69-189E-4F3E-B521-32BDC1121E5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {74641C69-189E-4F3E-B521-32BDC1121E5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {74641C69-189E-4F3E-B521-32BDC1121E5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {74641C69-189E-4F3E-B521-32BDC1121E5F}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Database/Oracle.OleDb/Example.cs b/examples/targets/Configuration API/Database/Oracle.OleDb/Example.cs
new file mode 100644
index 0000000..bc6f019
--- /dev/null
+++ b/examples/targets/Configuration API/Database/Oracle.OleDb/Example.cs
@@ -0,0 +1,26 @@
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ DatabaseTarget target = new DatabaseTarget();
+ DatabaseParameterInfo param;
+
+ target.DBProvider = "oledb";
+ target.ConnectionString = "Provider=msdaora;Data Source=MYORACLEDB;User Id=DBO;Password=MYPASSWORD;";
+ target.CommandText = "insert into LOGTABLE( TIME_STAMP,LOGLEVEL,LOGGER,CALLSITE,MESSAGE) values(?,?,?,?,?)";
+
+ target.Parameters.Add(new DatabaseParameterInfo("TIME_STAMP", "${longdate}"));
+ target.Parameters.Add(new DatabaseParameterInfo("LOGLEVEL", "${level:uppercase=true}"));
+ target.Parameters.Add(new DatabaseParameterInfo("LOGGER", "${logger}"));
+ target.Parameters.Add(new DatabaseParameterInfo("CALLSITE", "${callsite:filename=true}"));
+ target.Parameters.Add(new DatabaseParameterInfo("MESSAGE", "${message}"));
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/Debug/Simple/Debug.csproj b/examples/targets/Configuration API/Debug/Simple/Debug.csproj
new file mode 100644
index 0000000..bcb501c
--- /dev/null
+++ b/examples/targets/Configuration API/Debug/Simple/Debug.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{D0526912-F1E9-4D30-941F-3A229DCC9309}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Debug</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/Debug/Simple/Debug.sln b/examples/targets/Configuration API/Debug/Simple/Debug.sln
new file mode 100644
index 0000000..190feeb
--- /dev/null
+++ b/examples/targets/Configuration API/Debug/Simple/Debug.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debug", "Debug.csproj", "{D0526912-F1E9-4D30-941F-3A229DCC9309}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D0526912-F1E9-4D30-941F-3A229DCC9309}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D0526912-F1E9-4D30-941F-3A229DCC9309}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D0526912-F1E9-4D30-941F-3A229DCC9309}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D0526912-F1E9-4D30-941F-3A229DCC9309}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Debug/Simple/Example.cs b/examples/targets/Configuration API/Debug/Simple/Example.cs
new file mode 100644
index 0000000..6d49fe8
--- /dev/null
+++ b/examples/targets/Configuration API/Debug/Simple/Example.cs
@@ -0,0 +1,22 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ DebugTarget target = new DebugTarget();
+ target.Layout = "${message}";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ logger.Debug("another log message");
+
+ Console.WriteLine("The debug target has been hit {0} times.", target.Counter);
+ Console.WriteLine("The last message was '{0}'.", target.LastMessage);
+ }
+}
diff --git a/examples/targets/Configuration API/Debugger/Simple/Debugger.csproj b/examples/targets/Configuration API/Debugger/Simple/Debugger.csproj
new file mode 100644
index 0000000..9be8e20
--- /dev/null
+++ b/examples/targets/Configuration API/Debugger/Simple/Debugger.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{7720B322-2AFF-45C4-AF9A-EAB12BCFAFCE}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Debugger</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/Debugger/Simple/Debugger.sln b/examples/targets/Configuration API/Debugger/Simple/Debugger.sln
new file mode 100644
index 0000000..aa2584b
--- /dev/null
+++ b/examples/targets/Configuration API/Debugger/Simple/Debugger.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger", "Debugger.csproj", "{7720B322-2AFF-45C4-AF9A-EAB12BCFAFCE}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7720B322-2AFF-45C4-AF9A-EAB12BCFAFCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7720B322-2AFF-45C4-AF9A-EAB12BCFAFCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7720B322-2AFF-45C4-AF9A-EAB12BCFAFCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7720B322-2AFF-45C4-AF9A-EAB12BCFAFCE}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Debugger/Simple/Example.cs b/examples/targets/Configuration API/Debugger/Simple/Example.cs
new file mode 100644
index 0000000..0b233e5
--- /dev/null
+++ b/examples/targets/Configuration API/Debugger/Simple/Example.cs
@@ -0,0 +1,18 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ DebuggerTarget target = new DebuggerTarget();
+ target.Layout = "${message}";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/EventLog/Simple/EventLog.csproj b/examples/targets/Configuration API/EventLog/Simple/EventLog.csproj
new file mode 100644
index 0000000..8ae8b09
--- /dev/null
+++ b/examples/targets/Configuration API/EventLog/Simple/EventLog.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{D7347273-CF36-4A75-B324-90D4644D9287}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>EventLog</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/EventLog/Simple/EventLog.sln b/examples/targets/Configuration API/EventLog/Simple/EventLog.sln
new file mode 100644
index 0000000..c4b49e7
--- /dev/null
+++ b/examples/targets/Configuration API/EventLog/Simple/EventLog.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventLog", "EventLog.csproj", "{D7347273-CF36-4A75-B324-90D4644D9287}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D7347273-CF36-4A75-B324-90D4644D9287}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D7347273-CF36-4A75-B324-90D4644D9287}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D7347273-CF36-4A75-B324-90D4644D9287}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D7347273-CF36-4A75-B324-90D4644D9287}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/EventLog/Simple/Example.cs b/examples/targets/Configuration API/EventLog/Simple/Example.cs
new file mode 100644
index 0000000..2a99fa6
--- /dev/null
+++ b/examples/targets/Configuration API/EventLog/Simple/Example.cs
@@ -0,0 +1,20 @@
+using NLog;
+using NLog.Targets;
+using NLog.Win32.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ EventLogTarget target = new EventLogTarget();
+ target.Source = "My Source";
+ target.Log = "Application";
+ target.MachineName = ".";
+ target.Layout = "${logger}: ${message}";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/FallbackGroup/Simple/Example.cs b/examples/targets/Configuration API/FallbackGroup/Simple/Example.cs
new file mode 100644
index 0000000..02fa14e
--- /dev/null
+++ b/examples/targets/Configuration API/FallbackGroup/Simple/Example.cs
@@ -0,0 +1,31 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Compound;
+using System.Diagnostics;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget file1 = new FileTarget();
+ file1.FileName = "\\\\server1\\share\\file1.txt";
+
+ FileTarget file2 = new FileTarget();
+ file2.FileName = "\\\\server2\\share\\file1.txt";
+
+
+ // write to server1, if it fails switch to server2
+ FallbackTarget target = new FallbackTarget();
+
+ target.ReturnToFirstOnSuccess = false;
+ target.Targets.Add(file1);
+ target.Targets.Add(file2);
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/FallbackGroup/Simple/FallbackGroup.csproj b/examples/targets/Configuration API/FallbackGroup/Simple/FallbackGroup.csproj
new file mode 100644
index 0000000..d9d1477
--- /dev/null
+++ b/examples/targets/Configuration API/FallbackGroup/Simple/FallbackGroup.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{08BA1481-13F1-4913-8BA6-EDE27AD01EE7}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>FallbackGroup</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/FallbackGroup/Simple/FallbackGroup.sln b/examples/targets/Configuration API/FallbackGroup/Simple/FallbackGroup.sln
new file mode 100644
index 0000000..afa87db
--- /dev/null
+++ b/examples/targets/Configuration API/FallbackGroup/Simple/FallbackGroup.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FallbackGroup", "FallbackGroup.csproj", "{08BA1481-13F1-4913-8BA6-EDE27AD01EE7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {08BA1481-13F1-4913-8BA6-EDE27AD01EE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {08BA1481-13F1-4913-8BA6-EDE27AD01EE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {08BA1481-13F1-4913-8BA6-EDE27AD01EE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {08BA1481-13F1-4913-8BA6-EDE27AD01EE7}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/File/Archive1/Example.cs b/examples/targets/Configuration API/File/Archive1/Example.cs
new file mode 100644
index 0000000..4db95ca
--- /dev/null
+++ b/examples/targets/Configuration API/File/Archive1/Example.cs
@@ -0,0 +1,29 @@
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget target = new FileTarget();
+ target.Layout = "${longdate} ${logger} ${message}";
+ target.FileName = "${basedir}/logs/logfile.txt";
+ target.ArchiveFileName = "${basedir}/archives/log.{#####}.txt";
+ target.ArchiveAboveSize = 10 * 1024; // archive files greater than 10 KB
+ target.ArchiveNumbering = FileTarget.ArchiveNumberingMode.Sequence;
+
+ // this speeds up things when no other processes are writing to the file
+ target.ConcurrentWrites = true;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+
+ // generate a large volume of messages
+ for (int i = 0; i < 1000; ++i)
+ {
+ logger.Debug("log message {0}", i);
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/File/Archive1/File.Archive1.csproj b/examples/targets/Configuration API/File/Archive1/File.Archive1.csproj
new file mode 100644
index 0000000..fb9daf6
--- /dev/null
+++ b/examples/targets/Configuration API/File/Archive1/File.Archive1.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{D8A33DCE-395C-4AD8-8FEC-74B8C8C74F53}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>File.Archive1</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/File/Archive1/File.Archive1.sln b/examples/targets/Configuration API/File/Archive1/File.Archive1.sln
new file mode 100644
index 0000000..05d1e1d
--- /dev/null
+++ b/examples/targets/Configuration API/File/Archive1/File.Archive1.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Archive1", "File.Archive1.csproj", "{D8A33DCE-395C-4AD8-8FEC-74B8C8C74F53}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D8A33DCE-395C-4AD8-8FEC-74B8C8C74F53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D8A33DCE-395C-4AD8-8FEC-74B8C8C74F53}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D8A33DCE-395C-4AD8-8FEC-74B8C8C74F53}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D8A33DCE-395C-4AD8-8FEC-74B8C8C74F53}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/File/Archive2/Example.cs b/examples/targets/Configuration API/File/Archive2/Example.cs
new file mode 100644
index 0000000..a9c10ed
--- /dev/null
+++ b/examples/targets/Configuration API/File/Archive2/Example.cs
@@ -0,0 +1,46 @@
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+using System.Threading;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget target = new FileTarget();
+ target.Layout = "${longdate} ${logger} ${message}";
+ target.FileName = "${basedir}/logs/logfile.txt";
+ target.ArchiveFileName = "${basedir}/archives/log.{#####}.txt";
+ target.ArchiveEvery = FileTarget.ArchiveEveryMode.Minute;
+ target.ArchiveNumbering = FileTarget.ArchiveNumberingMode.Rolling;
+ target.MaxArchiveFiles = 3;
+
+ // this speeds up things when no other processes are writing to the file
+ target.ConcurrentWrites = true;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+
+ // generate a large number of messages, sleeping 1 second between writes
+ // to observe time-based archiving which occurs every minute
+
+ //
+ // you get:
+ // logs/logfile.txt
+ //
+ // and your archives go to:
+ //
+ // archives/log.00000.txt
+ // archives/log.00001.txt
+ // archives/log.00002.txt
+ // archives/log.00003.txt
+ // archives/log.00004.txt
+
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Debug("log message {i}", i);
+ Thread.Sleep(1000);
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/File/Archive2/File.Archive2.csproj b/examples/targets/Configuration API/File/Archive2/File.Archive2.csproj
new file mode 100644
index 0000000..50e3655
--- /dev/null
+++ b/examples/targets/Configuration API/File/Archive2/File.Archive2.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{97DA6A8F-CF90-4E70-986E-E0A9D7196312}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>File.Archive2</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/File/Archive2/File.Archive2.sln b/examples/targets/Configuration API/File/Archive2/File.Archive2.sln
new file mode 100644
index 0000000..64f01a3
--- /dev/null
+++ b/examples/targets/Configuration API/File/Archive2/File.Archive2.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Archive2", "File.Archive2.csproj", "{97DA6A8F-CF90-4E70-986E-E0A9D7196312}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {97DA6A8F-CF90-4E70-986E-E0A9D7196312}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {97DA6A8F-CF90-4E70-986E-E0A9D7196312}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {97DA6A8F-CF90-4E70-986E-E0A9D7196312}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {97DA6A8F-CF90-4E70-986E-E0A9D7196312}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/File/Archive3/Example.cs b/examples/targets/Configuration API/File/Archive3/Example.cs
new file mode 100644
index 0000000..634f238
--- /dev/null
+++ b/examples/targets/Configuration API/File/Archive3/Example.cs
@@ -0,0 +1,50 @@
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+using System.Threading;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget target = new FileTarget();
+ target.Layout = "${longdate} ${logger} ${message}";
+ target.FileName = "${basedir}/logs/logfile.txt";
+ // where to store the archive files
+ target.ArchiveFileName = "${basedir}/archives/log.{#####}.txt";
+ target.ArchiveEvery = FileTarget.ArchiveEveryMode.Minute;
+ target.ArchiveNumbering = FileTarget.ArchiveNumberingMode.Rolling;
+ target.MaxArchiveFiles = 3;
+ target.ArchiveAboveSize = 10000;
+
+ // this speeds up things when no other processes are writing to the file
+ target.ConcurrentWrites = true;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+
+ // generate a large number of messages, sleeping 1/10 of second between writes
+ // to observe time-based archiving which occurs every minute
+ // the volume is high enough to cause ArchiveAboveSize to be triggered
+ // so that log files larger than 10000 bytes are archived as well
+
+ //
+ // you get:
+ // logs/logfile.txt
+ //
+ // and your archives go to:
+ //
+ // archives/log.00000.txt
+ // archives/log.00001.txt
+ // archives/log.00002.txt
+ // archives/log.00003.txt
+ // archives/log.00004.txt
+
+ for (int i = 0; i < 2500; ++i)
+ {
+ logger.Debug("log message {i}", i);
+ Thread.Sleep(100);
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/File/Archive3/File.Archive3.csproj b/examples/targets/Configuration API/File/Archive3/File.Archive3.csproj
new file mode 100644
index 0000000..5657906
--- /dev/null
+++ b/examples/targets/Configuration API/File/Archive3/File.Archive3.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{400AFAB6-9354-49AB-A001-00B09235CEF1}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>File.Archive3</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/File/Archive3/File.Archive3.sln b/examples/targets/Configuration API/File/Archive3/File.Archive3.sln
new file mode 100644
index 0000000..f2ce0b6
--- /dev/null
+++ b/examples/targets/Configuration API/File/Archive3/File.Archive3.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Archive3", "File.Archive3.csproj", "{400AFAB6-9354-49AB-A001-00B09235CEF1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {400AFAB6-9354-49AB-A001-00B09235CEF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {400AFAB6-9354-49AB-A001-00B09235CEF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {400AFAB6-9354-49AB-A001-00B09235CEF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {400AFAB6-9354-49AB-A001-00B09235CEF1}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/File/Archive4/Example.cs b/examples/targets/Configuration API/File/Archive4/Example.cs
new file mode 100644
index 0000000..32c563b
--- /dev/null
+++ b/examples/targets/Configuration API/File/Archive4/Example.cs
@@ -0,0 +1,63 @@
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+using System.Threading;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget target = new FileTarget();
+ target.Layout = "${longdate} ${logger} ${message}";
+ target.FileName = "${basedir}/logs/logfile.${level}.txt";
+ // where to store the archive files
+ target.ArchiveFileName = "${basedir}/archives/${level}/log.{#####}.txt";
+ target.ArchiveEvery = FileTarget.ArchiveEveryMode.Minute;
+ target.ArchiveNumbering = FileTarget.ArchiveNumberingMode.Rolling;
+ target.MaxArchiveFiles = 3;
+ target.ArchiveAboveSize = 10000;
+
+ // this speeds up things when no other processes are writing to the file
+ target.ConcurrentWrites = true;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+
+ // generate a large number of messages, sleeping 1/10 of second between writes
+ // to observe time-based archiving which occurs every minute
+ // the volume is high enough to cause ArchiveAboveSize to be triggered
+ // so that log files larger than 10000 bytes are archived as well
+
+ // in this version, a single File target keeps track of 3 sets of log and
+ // archive files, one for each level
+
+ // you get:
+ // logs/logfile.Debug.txt
+ // logs/logfile.Error.txt
+ // logs/logfile.Fatal.txt
+ //
+ // and your archives go to:
+ //
+ // archives/Debug/log.00000.txt
+ // archives/Debug/log.00001.txt
+ // archives/Debug/log.00002.txt
+ // archives/Debug/log.00003.txt
+ // archives/Error/log.00000.txt
+ // archives/Error/log.00001.txt
+ // archives/Error/log.00002.txt
+ // archives/Error/log.00003.txt
+ // archives/Fatal/log.00000.txt
+ // archives/Fatal/log.00001.txt
+ // archives/Fatal/log.00002.txt
+ // archives/Fatal/log.00003.txt
+
+ for (int i = 0; i < 2500; ++i)
+ {
+ logger.Debug("log message {i}", i);
+ logger.Error("log message {i}", i);
+ logger.Fatal("log message {i}", i);
+ Thread.Sleep(100);
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/File/Archive4/File.Archive4.csproj b/examples/targets/Configuration API/File/Archive4/File.Archive4.csproj
new file mode 100644
index 0000000..c252231
--- /dev/null
+++ b/examples/targets/Configuration API/File/Archive4/File.Archive4.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{F1BC69B4-E41C-4E72-AA57-FBF73663CAEB}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>File.Archive4</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/File/Archive4/File.Archive4.sln b/examples/targets/Configuration API/File/Archive4/File.Archive4.sln
new file mode 100644
index 0000000..d22645b
--- /dev/null
+++ b/examples/targets/Configuration API/File/Archive4/File.Archive4.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Archive4", "File.Archive4.csproj", "{F1BC69B4-E41C-4E72-AA57-FBF73663CAEB}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F1BC69B4-E41C-4E72-AA57-FBF73663CAEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F1BC69B4-E41C-4E72-AA57-FBF73663CAEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F1BC69B4-E41C-4E72-AA57-FBF73663CAEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F1BC69B4-E41C-4E72-AA57-FBF73663CAEB}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/File/Asynchronous/Example.cs b/examples/targets/Configuration API/File/Asynchronous/Example.cs
new file mode 100644
index 0000000..69ffe6e
--- /dev/null
+++ b/examples/targets/Configuration API/File/Asynchronous/Example.cs
@@ -0,0 +1,25 @@
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget target = new FileTarget();
+ target.Layout = "${longdate} ${logger} ${message}";
+ target.FileName = "${basedir}/logs/logfile.txt";
+ target.KeepFileOpen = false;
+ target.Encoding = "iso-8859-2";
+
+ AsyncTargetWrapper wrapper = new AsyncTargetWrapper();
+ wrapper.WrappedTarget = target;
+ wrapper.QueueLimit = 5000;
+ wrapper.OverflowAction = AsyncTargetWrapperOverflowAction.Discard;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(wrapper, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/File/Asynchronous/File.Asynchronous.csproj b/examples/targets/Configuration API/File/Asynchronous/File.Asynchronous.csproj
new file mode 100644
index 0000000..a2f6631
--- /dev/null
+++ b/examples/targets/Configuration API/File/Asynchronous/File.Asynchronous.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{D26A09EB-2F43-4566-B304-81CF8055AD6B}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>File.Asynchronous</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/File/Asynchronous/File.Asynchronous.sln b/examples/targets/Configuration API/File/Asynchronous/File.Asynchronous.sln
new file mode 100644
index 0000000..2e2407a
--- /dev/null
+++ b/examples/targets/Configuration API/File/Asynchronous/File.Asynchronous.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Asynchronous", "File.Asynchronous.csproj", "{D26A09EB-2F43-4566-B304-81CF8055AD6B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D26A09EB-2F43-4566-B304-81CF8055AD6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D26A09EB-2F43-4566-B304-81CF8055AD6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D26A09EB-2F43-4566-B304-81CF8055AD6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D26A09EB-2F43-4566-B304-81CF8055AD6B}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/File/CSV/Example.cs b/examples/targets/Configuration API/File/CSV/Example.cs
new file mode 100644
index 0000000..393f2ac
--- /dev/null
+++ b/examples/targets/Configuration API/File/CSV/Example.cs
@@ -0,0 +1,29 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Layouts;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget target = new FileTarget();
+ target.FileName = "${basedir}/file.csv";
+
+ CsvLayout layout = new CsvLayout();
+
+ layout.Columns.Add(new CsvColumn("time", "${longdate}"));
+ layout.Columns.Add(new CsvColumn("message", "${message}"));
+ layout.Columns.Add(new CsvColumn("logger", "${logger}"));
+ layout.Columns.Add(new CsvColumn("level", "${level}"));
+
+ target.CompiledLayout = layout;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ logger.Debug("Message with \"quotes\" and \nnew line characters.");
+ }
+}
diff --git a/examples/targets/Configuration API/File/CSV/File.CSV.csproj b/examples/targets/Configuration API/File/CSV/File.CSV.csproj
new file mode 100644
index 0000000..cb97688
--- /dev/null
+++ b/examples/targets/Configuration API/File/CSV/File.CSV.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{B55FBAF5-21E0-4375-8515-0FF9622D581E}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>File.CSV</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/File/CSV/File.CSV.sln b/examples/targets/Configuration API/File/CSV/File.CSV.sln
new file mode 100644
index 0000000..85ba36f
--- /dev/null
+++ b/examples/targets/Configuration API/File/CSV/File.CSV.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.CSV", "File.CSV.csproj", "{B55FBAF5-21E0-4375-8515-0FF9622D581E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B55FBAF5-21E0-4375-8515-0FF9622D581E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B55FBAF5-21E0-4375-8515-0FF9622D581E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B55FBAF5-21E0-4375-8515-0FF9622D581E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B55FBAF5-21E0-4375-8515-0FF9622D581E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/File/Multiple/Example.cs b/examples/targets/Configuration API/File/Multiple/Example.cs
new file mode 100644
index 0000000..d30aad0
--- /dev/null
+++ b/examples/targets/Configuration API/File/Multiple/Example.cs
@@ -0,0 +1,19 @@
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget target = new FileTarget();
+ target.Layout = "${longdate} ${logger} ${message}";
+ target.FileName = "${basedir}/${level}.log";
+ target.KeepFileOpen = false;
+ target.Encoding = "iso-8859-2";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/File/Multiple/File.Multiple.csproj b/examples/targets/Configuration API/File/Multiple/File.Multiple.csproj
new file mode 100644
index 0000000..685d81d
--- /dev/null
+++ b/examples/targets/Configuration API/File/Multiple/File.Multiple.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{45DC6DFF-4680-4739-8DD1-3EA91C1E2F19}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>File.Multiple</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/File/Multiple/File.Multiple.sln b/examples/targets/Configuration API/File/Multiple/File.Multiple.sln
new file mode 100644
index 0000000..e544f55
--- /dev/null
+++ b/examples/targets/Configuration API/File/Multiple/File.Multiple.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Multiple", "File.Multiple.csproj", "{45DC6DFF-4680-4739-8DD1-3EA91C1E2F19}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {45DC6DFF-4680-4739-8DD1-3EA91C1E2F19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {45DC6DFF-4680-4739-8DD1-3EA91C1E2F19}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {45DC6DFF-4680-4739-8DD1-3EA91C1E2F19}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {45DC6DFF-4680-4739-8DD1-3EA91C1E2F19}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/File/Multiple2/Example.cs b/examples/targets/Configuration API/File/Multiple2/Example.cs
new file mode 100644
index 0000000..c55dd51
--- /dev/null
+++ b/examples/targets/Configuration API/File/Multiple2/Example.cs
@@ -0,0 +1,19 @@
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget target = new FileTarget();
+ target.Layout = "${longdate} ${logger} ${message}";
+ target.FileName = "${basedir}/${shortdate}/${windows-identity:domain=false}.${level}.log";
+ target.KeepFileOpen = false;
+ target.Encoding = "iso-8859-2";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/File/Multiple2/File.Multiple2.csproj b/examples/targets/Configuration API/File/Multiple2/File.Multiple2.csproj
new file mode 100644
index 0000000..aa59e2a
--- /dev/null
+++ b/examples/targets/Configuration API/File/Multiple2/File.Multiple2.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{BE090500-80BA-45B8-A22F-114167DCF774}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>File.Multiple2</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/File/Multiple2/File.Multiple2.sln b/examples/targets/Configuration API/File/Multiple2/File.Multiple2.sln
new file mode 100644
index 0000000..59b3143
--- /dev/null
+++ b/examples/targets/Configuration API/File/Multiple2/File.Multiple2.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File.Multiple2", "File.Multiple2.csproj", "{BE090500-80BA-45B8-A22F-114167DCF774}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BE090500-80BA-45B8-A22F-114167DCF774}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BE090500-80BA-45B8-A22F-114167DCF774}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BE090500-80BA-45B8-A22F-114167DCF774}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BE090500-80BA-45B8-A22F-114167DCF774}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/File/Simple/Example.cs b/examples/targets/Configuration API/File/Simple/Example.cs
new file mode 100644
index 0000000..2723362
--- /dev/null
+++ b/examples/targets/Configuration API/File/Simple/Example.cs
@@ -0,0 +1,19 @@
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget target = new FileTarget();
+ target.Layout = "${longdate} ${logger} ${message}";
+ target.FileName = "${basedir}/logs/logfile.txt";
+ target.KeepFileOpen = false;
+ target.Encoding = "iso-8859-2";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/File/Simple/File.csproj b/examples/targets/Configuration API/File/Simple/File.csproj
new file mode 100644
index 0000000..43674e8
--- /dev/null
+++ b/examples/targets/Configuration API/File/Simple/File.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{22DFBCFD-BDC3-4CD1-8DE5-E6872ACF7DB0}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>File</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/File/Simple/File.sln b/examples/targets/Configuration API/File/Simple/File.sln
new file mode 100644
index 0000000..8400ad3
--- /dev/null
+++ b/examples/targets/Configuration API/File/Simple/File.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "File", "File.csproj", "{22DFBCFD-BDC3-4CD1-8DE5-E6872ACF7DB0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {22DFBCFD-BDC3-4CD1-8DE5-E6872ACF7DB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {22DFBCFD-BDC3-4CD1-8DE5-E6872ACF7DB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {22DFBCFD-BDC3-4CD1-8DE5-E6872ACF7DB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {22DFBCFD-BDC3-4CD1-8DE5-E6872ACF7DB0}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/FilteringWrapper/Simple/Example.cs b/examples/targets/Configuration API/FilteringWrapper/Simple/Example.cs
new file mode 100644
index 0000000..b8e4862
--- /dev/null
+++ b/examples/targets/Configuration API/FilteringWrapper/Simple/Example.cs
@@ -0,0 +1,28 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+using System.Diagnostics;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget wrappedTarget = new FileTarget();
+ wrappedTarget.FileName = "${basedir}/file.txt";
+
+ FilteringTargetWrapper filteringTarget = new FilteringTargetWrapper();
+ filteringTarget.WrappedTarget = wrappedTarget;
+
+ filteringTarget.Condition = "contains('${message}','1')";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(filteringTarget, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message 0");
+ logger.Debug("log message 1");
+ logger.Debug("log message 2");
+ logger.Debug("log message 11");
+ }
+}
diff --git a/examples/targets/Configuration API/FilteringWrapper/Simple/FilteringWrapper.csproj b/examples/targets/Configuration API/FilteringWrapper/Simple/FilteringWrapper.csproj
new file mode 100644
index 0000000..72f23d2
--- /dev/null
+++ b/examples/targets/Configuration API/FilteringWrapper/Simple/FilteringWrapper.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{BFEDB63A-1A05-4A51-B7C2-C59DE01BC617}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>FilteringWrapper</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/FilteringWrapper/Simple/FilteringWrapper.sln b/examples/targets/Configuration API/FilteringWrapper/Simple/FilteringWrapper.sln
new file mode 100644
index 0000000..5c74849
--- /dev/null
+++ b/examples/targets/Configuration API/FilteringWrapper/Simple/FilteringWrapper.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FilteringWrapper", "FilteringWrapper.csproj", "{BFEDB63A-1A05-4A51-B7C2-C59DE01BC617}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BFEDB63A-1A05-4A51-B7C2-C59DE01BC617}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BFEDB63A-1A05-4A51-B7C2-C59DE01BC617}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BFEDB63A-1A05-4A51-B7C2-C59DE01BC617}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BFEDB63A-1A05-4A51-B7C2-C59DE01BC617}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/FormControl/Example.cs b/examples/targets/Configuration API/FormControl/Example.cs
new file mode 100644
index 0000000..a8a6b31
--- /dev/null
+++ b/examples/targets/Configuration API/FormControl/Example.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Windows.Forms;
+using NLog;
+using NLog.Targets;
+
+namespace RichTextBox2
+{
+ static class Example
+ {
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ // for NLog configuration look in Form1.cs
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/targets/Configuration API/FormControl/Form1.Designer.cs b/examples/targets/Configuration API/FormControl/Form1.Designer.cs
new file mode 100644
index 0000000..b996532
--- /dev/null
+++ b/examples/targets/Configuration API/FormControl/Form1.Designer.cs
@@ -0,0 +1,62 @@
+namespace RichTextBox2
+{
+ partial class Form1
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.SuspendLayout();
+ //
+ // textBox1
+ //
+ this.textBox1.Location = new System.Drawing.Point(12, 12);
+ this.textBox1.Multiline = true;
+ this.textBox1.Name = "textBox1";
+ this.textBox1.Size = new System.Drawing.Size(268, 242);
+ this.textBox1.TabIndex = 0;
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(292, 266);
+ this.Controls.Add(this.textBox1);
+ this.Name = "Form1";
+ this.Text = "Form1";
+ this.Load += new System.EventHandler(this.Form1_Load);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TextBox textBox1;
+
+ }
+}
+
diff --git a/examples/targets/Configuration API/FormControl/Form1.cs b/examples/targets/Configuration API/FormControl/Form1.cs
new file mode 100644
index 0000000..bc4c524
--- /dev/null
+++ b/examples/targets/Configuration API/FormControl/Form1.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Text;
+using System.Windows.Forms;
+using NLog;
+using NLog.Targets;
+
+namespace RichTextBox2
+{
+ public partial class Form1 : Form
+ {
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+
+ FormControlTarget target = new FormControlTarget();
+ target.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
+ target.ControlName = "textBox1";
+ target.FormName = "Form1";
+ target.Append = true;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Trace);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Trace("trace log message, ");
+ logger.Debug("debug log message, ");
+ logger.Info("info log message, ");
+ logger.Warn("warn log message, ");
+ logger.Error("error log message, ");
+ logger.Fatal("fatal log message");
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/targets/Configuration API/FormControl/Form1.resx b/examples/targets/Configuration API/FormControl/Form1.resx
new file mode 100644
index 0000000..ff31a6d
--- /dev/null
+++ b/examples/targets/Configuration API/FormControl/Form1.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/FormControl/FormControl.csproj b/examples/targets/Configuration API/FormControl/FormControl.csproj
new file mode 100644
index 0000000..5d25e4c
--- /dev/null
+++ b/examples/targets/Configuration API/FormControl/FormControl.csproj
@@ -0,0 +1,81 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{20449142-40C3-4B1D-8F7C-2D3ED924FDA7}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>RichTextBox</RootNamespace>
+ <AssemblyName>RichTextBox</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\..\build\net-2.0\bin\NLog.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Form1.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="Form1.Designer.cs">
+ <DependentUpon>Form1.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Example.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <EmbeddedResource Include="Form1.resx">
+ <SubType>Designer</SubType>
+ <DependentUpon>Form1.cs</DependentUpon>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/FormControl/FormControl.sln b/examples/targets/Configuration API/FormControl/FormControl.sln
new file mode 100644
index 0000000..e13af3f
--- /dev/null
+++ b/examples/targets/Configuration API/FormControl/FormControl.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FormControl", "FormControl.csproj", "{20449142-40C3-4B1D-8F7C-2D3ED924FDA7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/FormControl/Properties/AssemblyInfo.cs b/examples/targets/Configuration API/FormControl/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..cd4ef7a
--- /dev/null
+++ b/examples/targets/Configuration API/FormControl/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("FormmControl")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("MK")]
+[assembly: AssemblyProduct("FormControl")]
+[assembly: AssemblyCopyright("Copyright © MK 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("037e89f0-c093-4797-89d4-97b194dfdb98")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/examples/targets/Configuration API/FormControl/Properties/Resources.Designer.cs b/examples/targets/Configuration API/FormControl/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..71c8381
--- /dev/null
+++ b/examples/targets/Configuration API/FormControl/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace RichTextBox2.Properties
+{
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RichTextBox2.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/FormControl/Properties/Resources.resx b/examples/targets/Configuration API/FormControl/Properties/Resources.resx
new file mode 100644
index 0000000..ffecec8
--- /dev/null
+++ b/examples/targets/Configuration API/FormControl/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/FormControl/Properties/Settings.Designer.cs b/examples/targets/Configuration API/FormControl/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..e2486ab
--- /dev/null
+++ b/examples/targets/Configuration API/FormControl/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace RichTextBox2.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/FormControl/Properties/Settings.settings b/examples/targets/Configuration API/FormControl/Properties/Settings.settings
new file mode 100644
index 0000000..abf36c5
--- /dev/null
+++ b/examples/targets/Configuration API/FormControl/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile>
diff --git a/examples/targets/Configuration API/MSMQ/Multiple Queues/Example.cs b/examples/targets/Configuration API/MSMQ/Multiple Queues/Example.cs
new file mode 100644
index 0000000..3f09dbc
--- /dev/null
+++ b/examples/targets/Configuration API/MSMQ/Multiple Queues/Example.cs
@@ -0,0 +1,28 @@
+using NLog;
+using NLog.Config;
+using NLog.Win32.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ NLog.Internal.InternalLogger.LogToConsole = true;
+
+ MSMQTarget target = new MSMQTarget();
+ target.Queue = ".\\private$\\nlog.${level}";
+ target.Label = "${message}";
+ target.Layout = "${message}";
+ target.CreateQueueIfNotExists = true;
+ target.Recoverable = true;
+
+ SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Trace);
+
+ Logger l = LogManager.GetLogger("AAA");
+ l.Error("This is an error. It goes to .\\private$\\nlog.Error queue.");
+ l.Debug("This is a debug information. It goes to .\\private$\\nlog.Debug queue.");
+ l.Info("This is a information. It goes to .\\private$\\nlog.Info queue.");
+ l.Warn("This is a warn information. It goes to .\\private$\\nlog.Warn queue.");
+ l.Fatal("This is a fatal information. It goes to .\\private$\\nlog.Fatal queue.");
+ l.Trace("This is a trace information. It goes to .\\private$\\nlog.Trace queue.");
+ }
+}
diff --git a/examples/targets/Configuration API/MSMQ/Multiple Queues/MSMQ.Multiple Queues.csproj b/examples/targets/Configuration API/MSMQ/Multiple Queues/MSMQ.Multiple Queues.csproj
new file mode 100644
index 0000000..d97ab2c
--- /dev/null
+++ b/examples/targets/Configuration API/MSMQ/Multiple Queues/MSMQ.Multiple Queues.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{18924A56-9ACA-4835-887B-3F8956DA7391}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>MSMQ.Multiple Queues</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/MSMQ/Multiple Queues/MSMQ.Multiple Queues.sln b/examples/targets/Configuration API/MSMQ/Multiple Queues/MSMQ.Multiple Queues.sln
new file mode 100644
index 0000000..5058aff
--- /dev/null
+++ b/examples/targets/Configuration API/MSMQ/Multiple Queues/MSMQ.Multiple Queues.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSMQ.Multiple Queues", "MSMQ.Multiple Queues.csproj", "{18924A56-9ACA-4835-887B-3F8956DA7391}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {18924A56-9ACA-4835-887B-3F8956DA7391}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {18924A56-9ACA-4835-887B-3F8956DA7391}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {18924A56-9ACA-4835-887B-3F8956DA7391}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {18924A56-9ACA-4835-887B-3F8956DA7391}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/MSMQ/Simple/Example.cs b/examples/targets/Configuration API/MSMQ/Simple/Example.cs
new file mode 100644
index 0000000..f39bd1a
--- /dev/null
+++ b/examples/targets/Configuration API/MSMQ/Simple/Example.cs
@@ -0,0 +1,28 @@
+using NLog;
+using NLog.Config;
+using NLog.Win32.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ NLog.Internal.InternalLogger.LogToConsole = true;
+
+ MSMQTarget target = new MSMQTarget();
+ target.Queue = ".\\private$\\nlog";
+ target.Label = "${message}";
+ target.Layout = "${message}";
+ target.CreateQueueIfNotExists = true;
+ target.Recoverable = true;
+
+ SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Trace);
+
+ Logger l = LogManager.GetLogger("AAA");
+ l.Error("This is an error. It goes to .\\private$\\nlog queue.");
+ l.Debug("This is a debug information. It goes to .\\private$\\nlog queue.");
+ l.Info("This is a information. It goes to .\\private$\\nlog queue.");
+ l.Warn("This is a warn information. It goes to .\\private$\\nlog queue.");
+ l.Fatal("This is a fatal information. It goes to .\\private$\\nlog queue.");
+ l.Trace("This is a trace information. It goes to .\\private$\\nlog queue.");
+ }
+}
diff --git a/examples/targets/Configuration API/MSMQ/Simple/MSMQ.csproj b/examples/targets/Configuration API/MSMQ/Simple/MSMQ.csproj
new file mode 100644
index 0000000..5328e91
--- /dev/null
+++ b/examples/targets/Configuration API/MSMQ/Simple/MSMQ.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{5D70009B-698D-4A42-99F8-6C4CEE500AD8}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>MSMQ</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/MSMQ/Simple/MSMQ.sln b/examples/targets/Configuration API/MSMQ/Simple/MSMQ.sln
new file mode 100644
index 0000000..a77ee6e
--- /dev/null
+++ b/examples/targets/Configuration API/MSMQ/Simple/MSMQ.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSMQ", "MSMQ.csproj", "{5D70009B-698D-4A42-99F8-6C4CEE500AD8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5D70009B-698D-4A42-99F8-6C4CEE500AD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5D70009B-698D-4A42-99F8-6C4CEE500AD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5D70009B-698D-4A42-99F8-6C4CEE500AD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5D70009B-698D-4A42-99F8-6C4CEE500AD8}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Mail/Buffered/Example.cs b/examples/targets/Configuration API/Mail/Buffered/Example.cs
new file mode 100644
index 0000000..a14679e
--- /dev/null
+++ b/examples/targets/Configuration API/Mail/Buffered/Example.cs
@@ -0,0 +1,48 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ try
+ {
+ NLog.Internal.InternalLogger.LogToConsole = true;
+ NLog.Internal.InternalLogger.LogLevel = LogLevel.Trace;
+ Console.WriteLine("Setting up the target...");
+ MailTarget target = new MailTarget();
+
+ target.SmtpServer = "192.168.0.15";
+ target.From = "jaak at jkowalski.net";
+ target.To = "jaak at jkowalski.net";
+ target.Subject = "sample subject";
+ target.Body = "${message}${newline}";
+
+ BufferingTargetWrapper buffer = new BufferingTargetWrapper(target, 5);
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(buffer, LogLevel.Debug);
+
+ Console.WriteLine("Sending...");
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message 1");
+ logger.Debug("log message 2");
+ logger.Debug("log message 3");
+ logger.Debug("log message 4");
+ logger.Debug("log message 5");
+ logger.Debug("log message 6");
+ logger.Debug("log message 7");
+ logger.Debug("log message 8");
+
+ // this should send 2 mails - one with messages 1..5, the other with messages 6..8
+ Console.WriteLine("Sent.");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("EX: {0}", ex);
+
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/Mail/Buffered/Mail.Buffered.csproj b/examples/targets/Configuration API/Mail/Buffered/Mail.Buffered.csproj
new file mode 100644
index 0000000..44071dc
--- /dev/null
+++ b/examples/targets/Configuration API/Mail/Buffered/Mail.Buffered.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{4D14B05B-437D-4D83-A52E-526DEBF68999}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Mail.Buffered</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/Mail/Buffered/Mail.Buffered.sln b/examples/targets/Configuration API/Mail/Buffered/Mail.Buffered.sln
new file mode 100644
index 0000000..0925293
--- /dev/null
+++ b/examples/targets/Configuration API/Mail/Buffered/Mail.Buffered.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mail.Buffered", "Mail.Buffered.csproj", "{4D14B05B-437D-4D83-A52E-526DEBF68999}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4D14B05B-437D-4D83-A52E-526DEBF68999}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4D14B05B-437D-4D83-A52E-526DEBF68999}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4D14B05B-437D-4D83-A52E-526DEBF68999}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4D14B05B-437D-4D83-A52E-526DEBF68999}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Mail/Simple/Example.cs b/examples/targets/Configuration API/Mail/Simple/Example.cs
new file mode 100644
index 0000000..c4ee72e
--- /dev/null
+++ b/examples/targets/Configuration API/Mail/Simple/Example.cs
@@ -0,0 +1,33 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ try
+ {
+ Console.WriteLine("Setting up the target...");
+ MailTarget target = new MailTarget();
+
+ target.SmtpServer = "192.168.0.15";
+ target.From = "jaak at jkowalski.net";
+ target.To = "jaak at jkowalski.net";
+ target.Subject = "sample subject";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Console.WriteLine("Sending...");
+ Logger logger = LogManager.GetLogger("Example");
+ Console.WriteLine("Sent.");
+ logger.Debug("log message");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("EX: {0}", ex);
+
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/Mail/Simple/Mail.csproj b/examples/targets/Configuration API/Mail/Simple/Mail.csproj
new file mode 100644
index 0000000..a88e52b
--- /dev/null
+++ b/examples/targets/Configuration API/Mail/Simple/Mail.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{4132306C-EA25-4073-BFD5-BEBD9A88B600}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Mail</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/Mail/Simple/Mail.sln b/examples/targets/Configuration API/Mail/Simple/Mail.sln
new file mode 100644
index 0000000..a0b4aa4
--- /dev/null
+++ b/examples/targets/Configuration API/Mail/Simple/Mail.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mail", "Mail.csproj", "{4132306C-EA25-4073-BFD5-BEBD9A88B600}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4132306C-EA25-4073-BFD5-BEBD9A88B600}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4132306C-EA25-4073-BFD5-BEBD9A88B600}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4132306C-EA25-4073-BFD5-BEBD9A88B600}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4132306C-EA25-4073-BFD5-BEBD9A88B600}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Memory/Simple/Example.cs b/examples/targets/Configuration API/Memory/Simple/Example.cs
new file mode 100644
index 0000000..3923ccb
--- /dev/null
+++ b/examples/targets/Configuration API/Memory/Simple/Example.cs
@@ -0,0 +1,23 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ MemoryTarget target = new MemoryTarget();
+ target.Layout = "${message}";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+
+ foreach (string s in target.Logs)
+ {
+ Console.Write("logged: {0}", s);
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/Memory/Simple/Memory.csproj b/examples/targets/Configuration API/Memory/Simple/Memory.csproj
new file mode 100644
index 0000000..b1f14e7
--- /dev/null
+++ b/examples/targets/Configuration API/Memory/Simple/Memory.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{4D71290B-65DC-4442-BE06-1CEBE07A26AC}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Memory</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/Memory/Simple/Memory.sln b/examples/targets/Configuration API/Memory/Simple/Memory.sln
new file mode 100644
index 0000000..f65d47f
--- /dev/null
+++ b/examples/targets/Configuration API/Memory/Simple/Memory.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Memory", "Memory.csproj", "{4D71290B-65DC-4442-BE06-1CEBE07A26AC}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4D71290B-65DC-4442-BE06-1CEBE07A26AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4D71290B-65DC-4442-BE06-1CEBE07A26AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4D71290B-65DC-4442-BE06-1CEBE07A26AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4D71290B-65DC-4442-BE06-1CEBE07A26AC}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/MessageBox/Simple/Example.cs b/examples/targets/Configuration API/MessageBox/Simple/Example.cs
new file mode 100644
index 0000000..41e750b
--- /dev/null
+++ b/examples/targets/Configuration API/MessageBox/Simple/Example.cs
@@ -0,0 +1,19 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ MessageBoxTarget target = new MessageBoxTarget();
+ target.Layout = "${longdate}: ${message}";
+ target.Caption = "${level} message";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/MessageBox/Simple/MessageBox.csproj b/examples/targets/Configuration API/MessageBox/Simple/MessageBox.csproj
new file mode 100644
index 0000000..da28277
--- /dev/null
+++ b/examples/targets/Configuration API/MessageBox/Simple/MessageBox.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{26FC5FD6-F4E9-4E0F-BB0D-492AAE98D880}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>MessageBox</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/MessageBox/Simple/MessageBox.sln b/examples/targets/Configuration API/MessageBox/Simple/MessageBox.sln
new file mode 100644
index 0000000..93cb0b5
--- /dev/null
+++ b/examples/targets/Configuration API/MessageBox/Simple/MessageBox.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessageBox", "MessageBox.csproj", "{26FC5FD6-F4E9-4E0F-BB0D-492AAE98D880}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {26FC5FD6-F4E9-4E0F-BB0D-492AAE98D880}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {26FC5FD6-F4E9-4E0F-BB0D-492AAE98D880}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {26FC5FD6-F4E9-4E0F-BB0D-492AAE98D880}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {26FC5FD6-F4E9-4E0F-BB0D-492AAE98D880}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/MethodCall/Simple/Example.cs b/examples/targets/Configuration API/MethodCall/Simple/Example.cs
new file mode 100644
index 0000000..49dee78
--- /dev/null
+++ b/examples/targets/Configuration API/MethodCall/Simple/Example.cs
@@ -0,0 +1,27 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using System.Diagnostics;
+
+public class Example
+{
+ public static void LogMethod(string level, string message)
+ {
+ Console.WriteLine("l: {0} m: {1}", level, message);
+ }
+ static void Main(string[] args)
+ {
+ MethodCallTarget target = new MethodCallTarget();
+ target.ClassName = typeof(Example).AssemblyQualifiedName;
+ target.MethodName = "LogMethod";
+ target.Parameters.Add(new MethodCallParameter("${level}"));
+ target.Parameters.Add(new MethodCallParameter("${message}"));
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ logger.Error("error message");
+ }
+}
diff --git a/examples/targets/Configuration API/MethodCall/Simple/MethodCall.csproj b/examples/targets/Configuration API/MethodCall/Simple/MethodCall.csproj
new file mode 100644
index 0000000..6da4957
--- /dev/null
+++ b/examples/targets/Configuration API/MethodCall/Simple/MethodCall.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{8D851E55-9D32-4C20-A9CE-C1A35175D06E}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>MethodCall</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/MethodCall/Simple/MethodCall.sln b/examples/targets/Configuration API/MethodCall/Simple/MethodCall.sln
new file mode 100644
index 0000000..1c0c527
--- /dev/null
+++ b/examples/targets/Configuration API/MethodCall/Simple/MethodCall.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MethodCall", "MethodCall.csproj", "{8D851E55-9D32-4C20-A9CE-C1A35175D06E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8D851E55-9D32-4C20-A9CE-C1A35175D06E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8D851E55-9D32-4C20-A9CE-C1A35175D06E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8D851E55-9D32-4C20-A9CE-C1A35175D06E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8D851E55-9D32-4C20-A9CE-C1A35175D06E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/NLogViewer/Simple/Example.cs b/examples/targets/Configuration API/NLogViewer/Simple/Example.cs
new file mode 100644
index 0000000..c09894a
--- /dev/null
+++ b/examples/targets/Configuration API/NLogViewer/Simple/Example.cs
@@ -0,0 +1,21 @@
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ NLogViewerTarget target = new NLogViewerTarget();
+ target.Address = "udp://localhost:4000";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Trace("log message 1");
+ logger.Debug("log message 2");
+ logger.Info("log message 3");
+ logger.Warn("log message 4");
+ logger.Error("log message 5");
+ logger.Fatal("log message 6");
+ }
+}
diff --git a/examples/targets/Configuration API/NLogViewer/Simple/NLogViewer.csproj b/examples/targets/Configuration API/NLogViewer/Simple/NLogViewer.csproj
new file mode 100644
index 0000000..ff5846e
--- /dev/null
+++ b/examples/targets/Configuration API/NLogViewer/Simple/NLogViewer.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{36E8A9EF-C91F-443A-9FEF-B2AB27E3628A}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>NLogViewer</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/NLogViewer/Simple/NLogViewer.sln b/examples/targets/Configuration API/NLogViewer/Simple/NLogViewer.sln
new file mode 100644
index 0000000..70f31cd
--- /dev/null
+++ b/examples/targets/Configuration API/NLogViewer/Simple/NLogViewer.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLogViewer", "NLogViewer.csproj", "{36E8A9EF-C91F-443A-9FEF-B2AB27E3628A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {36E8A9EF-C91F-443A-9FEF-B2AB27E3628A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {36E8A9EF-C91F-443A-9FEF-B2AB27E3628A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {36E8A9EF-C91F-443A-9FEF-B2AB27E3628A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {36E8A9EF-C91F-443A-9FEF-B2AB27E3628A}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Network/Simple/Example.cs b/examples/targets/Configuration API/Network/Simple/Example.cs
new file mode 100644
index 0000000..e0e9391
--- /dev/null
+++ b/examples/targets/Configuration API/Network/Simple/Example.cs
@@ -0,0 +1,22 @@
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ NetworkTarget target = new NetworkTarget();
+ target.Layout = "${level} ${logger} ${message}${newline}";
+ target.Address = "tcp://localhost:5555";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Trace("log message 1");
+ logger.Debug("log message 2");
+ logger.Info("log message 3");
+ logger.Warn("log message 4");
+ logger.Error("log message 5");
+ logger.Fatal("log message 6");
+ }
+}
diff --git a/examples/targets/Configuration API/Network/Simple/Network.csproj b/examples/targets/Configuration API/Network/Simple/Network.csproj
new file mode 100644
index 0000000..eb45a72
--- /dev/null
+++ b/examples/targets/Configuration API/Network/Simple/Network.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{1D3835B8-779E-4053-B03E-AC5292A48FF0}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Network</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/Network/Simple/Network.sln b/examples/targets/Configuration API/Network/Simple/Network.sln
new file mode 100644
index 0000000..021cf1f
--- /dev/null
+++ b/examples/targets/Configuration API/Network/Simple/Network.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Network", "Network.csproj", "{1D3835B8-779E-4053-B03E-AC5292A48FF0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1D3835B8-779E-4053-B03E-AC5292A48FF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1D3835B8-779E-4053-B03E-AC5292A48FF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1D3835B8-779E-4053-B03E-AC5292A48FF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1D3835B8-779E-4053-B03E-AC5292A48FF0}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Null/Simple/Example.cs b/examples/targets/Configuration API/Null/Simple/Example.cs
new file mode 100644
index 0000000..5967896
--- /dev/null
+++ b/examples/targets/Configuration API/Null/Simple/Example.cs
@@ -0,0 +1,19 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ NullTarget target = new NullTarget();
+ target.Layout = "${message}";
+ target.FormatMessage = true;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/Null/Simple/Null.csproj b/examples/targets/Configuration API/Null/Simple/Null.csproj
new file mode 100644
index 0000000..67b6bd9
--- /dev/null
+++ b/examples/targets/Configuration API/Null/Simple/Null.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{D32BF09E-4214-42B3-AB66-C6CAE9C3CEB1}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Null</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/Null/Simple/Null.sln b/examples/targets/Configuration API/Null/Simple/Null.sln
new file mode 100644
index 0000000..a139d64
--- /dev/null
+++ b/examples/targets/Configuration API/Null/Simple/Null.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Null", "Null.csproj", "{D32BF09E-4214-42B3-AB66-C6CAE9C3CEB1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D32BF09E-4214-42B3-AB66-C6CAE9C3CEB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D32BF09E-4214-42B3-AB66-C6CAE9C3CEB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D32BF09E-4214-42B3-AB66-C6CAE9C3CEB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D32BF09E-4214-42B3-AB66-C6CAE9C3CEB1}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/OutputDebugString/Simple/Example.cs b/examples/targets/Configuration API/OutputDebugString/Simple/Example.cs
new file mode 100644
index 0000000..4d6c2a5
--- /dev/null
+++ b/examples/targets/Configuration API/OutputDebugString/Simple/Example.cs
@@ -0,0 +1,19 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Win32.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ OutputDebugStringTarget target = new OutputDebugStringTarget();
+ target.Layout = "${message}";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/OutputDebugString/Simple/OutputDebugString.csproj b/examples/targets/Configuration API/OutputDebugString/Simple/OutputDebugString.csproj
new file mode 100644
index 0000000..ed340f4
--- /dev/null
+++ b/examples/targets/Configuration API/OutputDebugString/Simple/OutputDebugString.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{670A30F5-4957-4E96-9677-71A2A40975BA}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>OutputDebugString</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/OutputDebugString/Simple/OutputDebugString.sln b/examples/targets/Configuration API/OutputDebugString/Simple/OutputDebugString.sln
new file mode 100644
index 0000000..ed9d336
--- /dev/null
+++ b/examples/targets/Configuration API/OutputDebugString/Simple/OutputDebugString.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OutputDebugString", "OutputDebugString.csproj", "{670A30F5-4957-4E96-9677-71A2A40975BA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {670A30F5-4957-4E96-9677-71A2A40975BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {670A30F5-4957-4E96-9677-71A2A40975BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {670A30F5-4957-4E96-9677-71A2A40975BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {670A30F5-4957-4E96-9677-71A2A40975BA}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/PerfCounter/Simple/Example.cs b/examples/targets/Configuration API/PerfCounter/Simple/Example.cs
new file mode 100644
index 0000000..a63505d
--- /dev/null
+++ b/examples/targets/Configuration API/PerfCounter/Simple/Example.cs
@@ -0,0 +1,24 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Win32.Targets;
+using System.Diagnostics;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ PerfCounterTarget target = new PerfCounterTarget();
+ target.AutoCreate = true;
+ target.CategoryName = "My category";
+ target.CounterName = "My counter";
+ target.CounterType = PerformanceCounterType.NumberOfItems32;
+ target.InstanceName = "My instance";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/PerfCounter/Simple/PerfCounter.csproj b/examples/targets/Configuration API/PerfCounter/Simple/PerfCounter.csproj
new file mode 100644
index 0000000..776cc6f
--- /dev/null
+++ b/examples/targets/Configuration API/PerfCounter/Simple/PerfCounter.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{4C16C5D0-BB26-4639-8A2A-AEFCE8D3E5D6}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>PerfCounter</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/PerfCounter/Simple/PerfCounter.sln b/examples/targets/Configuration API/PerfCounter/Simple/PerfCounter.sln
new file mode 100644
index 0000000..5283a43
--- /dev/null
+++ b/examples/targets/Configuration API/PerfCounter/Simple/PerfCounter.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PerfCounter", "PerfCounter.csproj", "{4C16C5D0-BB26-4639-8A2A-AEFCE8D3E5D6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4C16C5D0-BB26-4639-8A2A-AEFCE8D3E5D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4C16C5D0-BB26-4639-8A2A-AEFCE8D3E5D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4C16C5D0-BB26-4639-8A2A-AEFCE8D3E5D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4C16C5D0-BB26-4639-8A2A-AEFCE8D3E5D6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/PostFilteringWrapper/Simple/Example.cs b/examples/targets/Configuration API/PostFilteringWrapper/Simple/Example.cs
new file mode 100644
index 0000000..a6f34b9
--- /dev/null
+++ b/examples/targets/Configuration API/PostFilteringWrapper/Simple/Example.cs
@@ -0,0 +1,41 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+using System.Diagnostics;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget wrappedTarget = new FileTarget();
+ wrappedTarget.FileName = "${basedir}/file.txt";
+
+ PostFilteringTargetWrapper postFilteringTarget = new PostFilteringTargetWrapper();
+ postFilteringTarget.WrappedTarget = wrappedTarget;
+
+ // set up default filter
+ postFilteringTarget.DefaultFilter = "level >= LogLevel.Info";
+
+ FilteringRule rule;
+
+ // if there are any warnings in the buffer
+ // dump the messages whose level is Debug or higher
+
+ rule = new FilteringRule();
+ rule.Exists = "level >= LogLevel.Warn";
+ rule.Filter = "level >= LogLevel.Debug";
+
+ postFilteringTarget.Rules.Add(rule);
+
+ BufferingTargetWrapper target = new BufferingTargetWrapper();
+ target.BufferSize = 100;
+ target.WrappedTarget = postFilteringTarget;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/PostFilteringWrapper/Simple/PostFilteringWrapper.csproj b/examples/targets/Configuration API/PostFilteringWrapper/Simple/PostFilteringWrapper.csproj
new file mode 100644
index 0000000..7f0240e
--- /dev/null
+++ b/examples/targets/Configuration API/PostFilteringWrapper/Simple/PostFilteringWrapper.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{B259D6E2-5376-42C1-8D05-6107BA9D1B0C}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>PostFilteringWrapper</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/PostFilteringWrapper/Simple/PostFilteringWrapper.sln b/examples/targets/Configuration API/PostFilteringWrapper/Simple/PostFilteringWrapper.sln
new file mode 100644
index 0000000..fa21ddc
--- /dev/null
+++ b/examples/targets/Configuration API/PostFilteringWrapper/Simple/PostFilteringWrapper.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PostFilteringWrapper", "PostFilteringWrapper.csproj", "{B259D6E2-5376-42C1-8D05-6107BA9D1B0C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B259D6E2-5376-42C1-8D05-6107BA9D1B0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B259D6E2-5376-42C1-8D05-6107BA9D1B0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B259D6E2-5376-42C1-8D05-6107BA9D1B0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B259D6E2-5376-42C1-8D05-6107BA9D1B0C}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/RandomizeGroup/Simple/Example.cs b/examples/targets/Configuration API/RandomizeGroup/Simple/Example.cs
new file mode 100644
index 0000000..990d17a
--- /dev/null
+++ b/examples/targets/Configuration API/RandomizeGroup/Simple/Example.cs
@@ -0,0 +1,27 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Compound;
+using System.Diagnostics;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget file1 = new FileTarget();
+ file1.FileName = "${basedir}/file1.txt";
+
+ FileTarget file2 = new FileTarget();
+ file2.FileName = "${basedir}/file2.txt";
+
+ RandomizeTarget target = new RandomizeTarget();
+ target.Targets.Add(file1);
+ target.Targets.Add(file2);
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/RandomizeGroup/Simple/RandomizeGroup.csproj b/examples/targets/Configuration API/RandomizeGroup/Simple/RandomizeGroup.csproj
new file mode 100644
index 0000000..834fc1f
--- /dev/null
+++ b/examples/targets/Configuration API/RandomizeGroup/Simple/RandomizeGroup.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{DE1A0AAC-8832-429D-90D2-360C11ADA8CE}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>RandomizeGroup</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RandomizeGroup/Simple/RandomizeGroup.sln b/examples/targets/Configuration API/RandomizeGroup/Simple/RandomizeGroup.sln
new file mode 100644
index 0000000..d51c762
--- /dev/null
+++ b/examples/targets/Configuration API/RandomizeGroup/Simple/RandomizeGroup.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RandomizeGroup", "RandomizeGroup.csproj", "{DE1A0AAC-8832-429D-90D2-360C11ADA8CE}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {DE1A0AAC-8832-429D-90D2-360C11ADA8CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DE1A0AAC-8832-429D-90D2-360C11ADA8CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DE1A0AAC-8832-429D-90D2-360C11ADA8CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DE1A0AAC-8832-429D-90D2-360C11ADA8CE}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/RepeatingWrapper/Simple/Example.cs b/examples/targets/Configuration API/RepeatingWrapper/Simple/Example.cs
new file mode 100644
index 0000000..78bebc1
--- /dev/null
+++ b/examples/targets/Configuration API/RepeatingWrapper/Simple/Example.cs
@@ -0,0 +1,24 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+using System.Diagnostics;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget wrappedTarget = new FileTarget();
+ wrappedTarget.FileName = "${basedir}/file.txt";
+
+ RepeatingTargetWrapper target = new RepeatingTargetWrapper();
+ target.WrappedTarget = wrappedTarget;
+ target.RepeatCount = 3;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/RepeatingWrapper/Simple/RepeatingWrapper.csproj b/examples/targets/Configuration API/RepeatingWrapper/Simple/RepeatingWrapper.csproj
new file mode 100644
index 0000000..d5b4220
--- /dev/null
+++ b/examples/targets/Configuration API/RepeatingWrapper/Simple/RepeatingWrapper.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{F7F3F62B-96E4-4FB9-8923-FB883E87520F}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>RepeatingWrapper</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RepeatingWrapper/Simple/RepeatingWrapper.sln b/examples/targets/Configuration API/RepeatingWrapper/Simple/RepeatingWrapper.sln
new file mode 100644
index 0000000..669e949
--- /dev/null
+++ b/examples/targets/Configuration API/RepeatingWrapper/Simple/RepeatingWrapper.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RepeatingWrapper", "RepeatingWrapper.csproj", "{F7F3F62B-96E4-4FB9-8923-FB883E87520F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F7F3F62B-96E4-4FB9-8923-FB883E87520F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F7F3F62B-96E4-4FB9-8923-FB883E87520F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F7F3F62B-96E4-4FB9-8923-FB883E87520F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F7F3F62B-96E4-4FB9-8923-FB883E87520F}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/RetryingWrapper/Simple/Example.cs b/examples/targets/Configuration API/RetryingWrapper/Simple/Example.cs
new file mode 100644
index 0000000..0890a93
--- /dev/null
+++ b/examples/targets/Configuration API/RetryingWrapper/Simple/Example.cs
@@ -0,0 +1,25 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+using System.Diagnostics;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget wrappedTarget = new FileTarget();
+ wrappedTarget.FileName = "${basedir}/file.txt";
+
+ RetryingTargetWrapper target = new RetryingTargetWrapper();
+ target.WrappedTarget = wrappedTarget;
+ target.RetryCount = 3;
+ target.RetryDelayMilliseconds = 1000;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/RetryingWrapper/Simple/RetryingWrapper.csproj b/examples/targets/Configuration API/RetryingWrapper/Simple/RetryingWrapper.csproj
new file mode 100644
index 0000000..f6a890e
--- /dev/null
+++ b/examples/targets/Configuration API/RetryingWrapper/Simple/RetryingWrapper.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{B2529445-C84E-4E3F-B4D7-651E9C195D39}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>RetryingWrapper</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RetryingWrapper/Simple/RetryingWrapper.sln b/examples/targets/Configuration API/RetryingWrapper/Simple/RetryingWrapper.sln
new file mode 100644
index 0000000..c3df51b
--- /dev/null
+++ b/examples/targets/Configuration API/RetryingWrapper/Simple/RetryingWrapper.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RetryingWrapper", "RetryingWrapper.csproj", "{B2529445-C84E-4E3F-B4D7-651E9C195D39}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B2529445-C84E-4E3F-B4D7-651E9C195D39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B2529445-C84E-4E3F-B4D7-651E9C195D39}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B2529445-C84E-4E3F-B4D7-651E9C195D39}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B2529445-C84E-4E3F-B4D7-651E9C195D39}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/RichTextBox/RowColoring/Example.cs b/examples/targets/Configuration API/RichTextBox/RowColoring/Example.cs
new file mode 100644
index 0000000..a8a6b31
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/RowColoring/Example.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Windows.Forms;
+using NLog;
+using NLog.Targets;
+
+namespace RichTextBox2
+{
+ static class Example
+ {
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ // for NLog configuration look in Form1.cs
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/RowColoring/Form1.Designer.cs b/examples/targets/Configuration API/RichTextBox/RowColoring/Form1.Designer.cs
new file mode 100644
index 0000000..900625e
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/RowColoring/Form1.Designer.cs
@@ -0,0 +1,61 @@
+namespace RichTextBox2
+{
+ partial class Form1
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.richTextBox1 = new System.Windows.Forms.RichTextBox();
+ this.SuspendLayout();
+ //
+ // richTextBox1
+ //
+ this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.richTextBox1.Location = new System.Drawing.Point(0, 0);
+ this.richTextBox1.Name = "richTextBox1";
+ this.richTextBox1.Size = new System.Drawing.Size(292, 266);
+ this.richTextBox1.TabIndex = 0;
+ this.richTextBox1.Text = "";
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(292, 266);
+ this.Controls.Add(this.richTextBox1);
+ this.Name = "Form1";
+ this.Text = "Form1";
+ this.Load += new System.EventHandler(this.Form1_Load);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.RichTextBox richTextBox1;
+ }
+}
+
diff --git a/examples/targets/Configuration API/RichTextBox/RowColoring/Form1.cs b/examples/targets/Configuration API/RichTextBox/RowColoring/Form1.cs
new file mode 100644
index 0000000..462e55f
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/RowColoring/Form1.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using NLog;
+using NLog.Targets;
+
+namespace RichTextBox2
+{
+ public partial class Form1 : Form
+ {
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+
+ RichTextBoxTarget target = new RichTextBoxTarget();
+ target.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
+ target.ControlName = "richTextBox1";
+ target.FormName = "Form1";
+ target.UseDefaultRowColoringRules = false;
+ target.RowColoringRules.Add(
+ new RichTextBoxRowColoringRule(
+ "level >= LogLevel.Error and contains(message,'serious')", // condition
+ "White", // font color
+ "Red", // background color
+ FontStyle.Bold | FontStyle.Italic
+ )
+ );
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Trace);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Trace("trace log message");
+ logger.Debug("debug log message");
+ logger.Info("info log message");
+ logger.Warn("warn log message");
+ logger.Error("error log message");
+ logger.Fatal("fatal log message");
+ logger.Fatal("fatal log message, rather serious");
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/RowColoring/Form1.resx b/examples/targets/Configuration API/RichTextBox/RowColoring/Form1.resx
new file mode 100644
index 0000000..ff31a6d
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/RowColoring/Form1.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/AssemblyInfo.cs b/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..e541e88
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("RichTextBox")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("MK")]
+[assembly: AssemblyProduct("RichTextBox")]
+[assembly: AssemblyCopyright("Copyright © MK 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("037e89f0-c093-4797-89d4-97b194dfdb98")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/Resources.Designer.cs b/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..71c8381
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace RichTextBox2.Properties
+{
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RichTextBox2.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/Resources.resx b/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/Resources.resx
new file mode 100644
index 0000000..ffecec8
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/Settings.Designer.cs b/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..e2486ab
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace RichTextBox2.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/Settings.settings b/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/Settings.settings
new file mode 100644
index 0000000..abf36c5
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/RowColoring/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile>
diff --git a/examples/targets/Configuration API/RichTextBox/RowColoring/RichTextBox.RowColoring.csproj b/examples/targets/Configuration API/RichTextBox/RowColoring/RichTextBox.RowColoring.csproj
new file mode 100644
index 0000000..039d368
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/RowColoring/RichTextBox.RowColoring.csproj
@@ -0,0 +1,81 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{0D0CED51-E850-4107-81F8-910F234E0F81}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>RichTextBox.RowColoring</RootNamespace>
+ <AssemblyName>RichTextBox.RowColoring</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\..\..\build\net-2.0\bin\NLog.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Form1.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="Form1.Designer.cs">
+ <DependentUpon>Form1.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Example.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <EmbeddedResource Include="Form1.resx">
+ <SubType>Designer</SubType>
+ <DependentUpon>Form1.cs</DependentUpon>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/RowColoring/RichTextBox.RowColoring.sln b/examples/targets/Configuration API/RichTextBox/RowColoring/RichTextBox.RowColoring.sln
new file mode 100644
index 0000000..0646490
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/RowColoring/RichTextBox.RowColoring.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RichTextBox", "RichTextBox.RowColoring.csproj", "{20449142-40C3-4B1D-8F7C-2D3ED924FDA7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/RichTextBox/Simple/Example.cs b/examples/targets/Configuration API/RichTextBox/Simple/Example.cs
new file mode 100644
index 0000000..a8a6b31
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/Simple/Example.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Windows.Forms;
+using NLog;
+using NLog.Targets;
+
+namespace RichTextBox2
+{
+ static class Example
+ {
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ // for NLog configuration look in Form1.cs
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/Simple/Form1.Designer.cs b/examples/targets/Configuration API/RichTextBox/Simple/Form1.Designer.cs
new file mode 100644
index 0000000..900625e
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/Simple/Form1.Designer.cs
@@ -0,0 +1,61 @@
+namespace RichTextBox2
+{
+ partial class Form1
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.richTextBox1 = new System.Windows.Forms.RichTextBox();
+ this.SuspendLayout();
+ //
+ // richTextBox1
+ //
+ this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.richTextBox1.Location = new System.Drawing.Point(0, 0);
+ this.richTextBox1.Name = "richTextBox1";
+ this.richTextBox1.Size = new System.Drawing.Size(292, 266);
+ this.richTextBox1.TabIndex = 0;
+ this.richTextBox1.Text = "";
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(292, 266);
+ this.Controls.Add(this.richTextBox1);
+ this.Name = "Form1";
+ this.Text = "Form1";
+ this.Load += new System.EventHandler(this.Form1_Load);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.RichTextBox richTextBox1;
+ }
+}
+
diff --git a/examples/targets/Configuration API/RichTextBox/Simple/Form1.cs b/examples/targets/Configuration API/RichTextBox/Simple/Form1.cs
new file mode 100644
index 0000000..b0a98e4
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/Simple/Form1.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Text;
+using System.Windows.Forms;
+using NLog;
+using NLog.Targets;
+
+namespace RichTextBox2
+{
+ public partial class Form1 : Form
+ {
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+
+ RichTextBoxTarget target = new RichTextBoxTarget();
+ target.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
+ target.ControlName = "richTextBox1";
+ target.FormName = "Form1";
+ target.UseDefaultRowColoringRules = true;
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Trace);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Trace("trace log message");
+ logger.Debug("debug log message");
+ logger.Info("info log message");
+ logger.Warn("warn log message");
+ logger.Error("error log message");
+ logger.Fatal("fatal log message");
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/Simple/Form1.resx b/examples/targets/Configuration API/RichTextBox/Simple/Form1.resx
new file mode 100644
index 0000000..ff31a6d
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/Simple/Form1.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/Simple/Properties/AssemblyInfo.cs b/examples/targets/Configuration API/RichTextBox/Simple/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..e541e88
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/Simple/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("RichTextBox")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("MK")]
+[assembly: AssemblyProduct("RichTextBox")]
+[assembly: AssemblyCopyright("Copyright © MK 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("037e89f0-c093-4797-89d4-97b194dfdb98")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/examples/targets/Configuration API/RichTextBox/Simple/Properties/Resources.Designer.cs b/examples/targets/Configuration API/RichTextBox/Simple/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..71c8381
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/Simple/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace RichTextBox2.Properties
+{
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RichTextBox2.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/RichTextBox/Simple/Properties/Resources.resx b/examples/targets/Configuration API/RichTextBox/Simple/Properties/Resources.resx
new file mode 100644
index 0000000..ffecec8
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/Simple/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/Simple/Properties/Settings.Designer.cs b/examples/targets/Configuration API/RichTextBox/Simple/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..e2486ab
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/Simple/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace RichTextBox2.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/RichTextBox/Simple/Properties/Settings.settings b/examples/targets/Configuration API/RichTextBox/Simple/Properties/Settings.settings
new file mode 100644
index 0000000..abf36c5
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/Simple/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile>
diff --git a/examples/targets/Configuration API/RichTextBox/Simple/RichTextBox.csproj b/examples/targets/Configuration API/RichTextBox/Simple/RichTextBox.csproj
new file mode 100644
index 0000000..16d7776
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/Simple/RichTextBox.csproj
@@ -0,0 +1,81 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{C6308AED-8472-4CCA-B49C-4AE9EBCE9DC8}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>RichTextBox</RootNamespace>
+ <AssemblyName>RichTextBox</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\..\..\build\net-2.0\bin\NLog.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Form1.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="Form1.Designer.cs">
+ <DependentUpon>Form1.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Example.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <EmbeddedResource Include="Form1.resx">
+ <SubType>Designer</SubType>
+ <DependentUpon>Form1.cs</DependentUpon>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/Simple/RichTextBox.sln b/examples/targets/Configuration API/RichTextBox/Simple/RichTextBox.sln
new file mode 100644
index 0000000..15e731f
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/Simple/RichTextBox.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RichTextBox", "RichTextBox.csproj", "{20449142-40C3-4B1D-8F7C-2D3ED924FDA7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/RichTextBox/WordColoring/Example.cs b/examples/targets/Configuration API/RichTextBox/WordColoring/Example.cs
new file mode 100644
index 0000000..a8a6b31
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/WordColoring/Example.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Windows.Forms;
+using NLog;
+using NLog.Targets;
+
+namespace RichTextBox2
+{
+ static class Example
+ {
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ // for NLog configuration look in Form1.cs
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/WordColoring/Form1.Designer.cs b/examples/targets/Configuration API/RichTextBox/WordColoring/Form1.Designer.cs
new file mode 100644
index 0000000..900625e
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/WordColoring/Form1.Designer.cs
@@ -0,0 +1,61 @@
+namespace RichTextBox2
+{
+ partial class Form1
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.richTextBox1 = new System.Windows.Forms.RichTextBox();
+ this.SuspendLayout();
+ //
+ // richTextBox1
+ //
+ this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.richTextBox1.Location = new System.Drawing.Point(0, 0);
+ this.richTextBox1.Name = "richTextBox1";
+ this.richTextBox1.Size = new System.Drawing.Size(292, 266);
+ this.richTextBox1.TabIndex = 0;
+ this.richTextBox1.Text = "";
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(292, 266);
+ this.Controls.Add(this.richTextBox1);
+ this.Name = "Form1";
+ this.Text = "Form1";
+ this.Load += new System.EventHandler(this.Form1_Load);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.RichTextBox richTextBox1;
+ }
+}
+
diff --git a/examples/targets/Configuration API/RichTextBox/WordColoring/Form1.cs b/examples/targets/Configuration API/RichTextBox/WordColoring/Form1.cs
new file mode 100644
index 0000000..9703c90
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/WordColoring/Form1.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using NLog;
+using NLog.Targets;
+
+namespace RichTextBox2
+{
+ public partial class Form1 : Form
+ {
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+
+ RichTextBoxTarget target = new RichTextBoxTarget();
+ target.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
+ target.ControlName = "richTextBox1";
+ target.FormName = "Form1";
+ target.UseDefaultRowColoringRules = false;
+ target.WordColoringRules.Add(
+ new RichTextBoxWordColoringRule(
+ "log", // word
+ "White", // font color
+ "Red", // background color
+ FontStyle.Bold | FontStyle.Italic
+ )
+ );
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Trace);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Trace("trace log message");
+ logger.Debug("debug log message");
+ logger.Info("info log message");
+ logger.Warn("warn log message");
+ logger.Error("error log message");
+ logger.Fatal("fatal log message");
+ logger.Fatal("fatal log message, rather serious");
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/WordColoring/Form1.resx b/examples/targets/Configuration API/RichTextBox/WordColoring/Form1.resx
new file mode 100644
index 0000000..ff31a6d
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/WordColoring/Form1.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/AssemblyInfo.cs b/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..e541e88
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("RichTextBox")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("MK")]
+[assembly: AssemblyProduct("RichTextBox")]
+[assembly: AssemblyCopyright("Copyright © MK 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("037e89f0-c093-4797-89d4-97b194dfdb98")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/Resources.Designer.cs b/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..71c8381
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace RichTextBox2.Properties
+{
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RichTextBox2.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/Resources.resx b/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/Resources.resx
new file mode 100644
index 0000000..ffecec8
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/Settings.Designer.cs b/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..e2486ab
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace RichTextBox2.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/Settings.settings b/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/Settings.settings
new file mode 100644
index 0000000..abf36c5
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/WordColoring/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile>
diff --git a/examples/targets/Configuration API/RichTextBox/WordColoring/RichTextBox.WordColoring.csproj b/examples/targets/Configuration API/RichTextBox/WordColoring/RichTextBox.WordColoring.csproj
new file mode 100644
index 0000000..a464674
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/WordColoring/RichTextBox.WordColoring.csproj
@@ -0,0 +1,81 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{7582650C-2D27-4AB1-9E2F-A93084A2AC79}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>RichTextBox.WordColoring</RootNamespace>
+ <AssemblyName>RichTextBox.WordColoring</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\..\..\build\net-2.0\bin\NLog.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Form1.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="Form1.Designer.cs">
+ <DependentUpon>Form1.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Example.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <EmbeddedResource Include="Form1.resx">
+ <SubType>Designer</SubType>
+ <DependentUpon>Form1.cs</DependentUpon>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RichTextBox/WordColoring/RichTextBox.WordColoring.sln b/examples/targets/Configuration API/RichTextBox/WordColoring/RichTextBox.WordColoring.sln
new file mode 100644
index 0000000..9aeb12a
--- /dev/null
+++ b/examples/targets/Configuration API/RichTextBox/WordColoring/RichTextBox.WordColoring.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RichTextBox", "RichTextBox.WordColoring.csproj", "{20449142-40C3-4B1D-8F7C-2D3ED924FDA7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {20449142-40C3-4B1D-8F7C-2D3ED924FDA7}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/RoundRobinGroup/Simple/Example.cs b/examples/targets/Configuration API/RoundRobinGroup/Simple/Example.cs
new file mode 100644
index 0000000..7c89a54
--- /dev/null
+++ b/examples/targets/Configuration API/RoundRobinGroup/Simple/Example.cs
@@ -0,0 +1,27 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Compound;
+using System.Diagnostics;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget file1 = new FileTarget();
+ file1.FileName = "${basedir}/file1.txt";
+
+ FileTarget file2 = new FileTarget();
+ file2.FileName = "${basedir}/file2.txt";
+
+ RoundRobinTarget target = new RoundRobinTarget();
+ target.Targets.Add(file1);
+ target.Targets.Add(file2);
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/RoundRobinGroup/Simple/RoundRobinGroup.csproj b/examples/targets/Configuration API/RoundRobinGroup/Simple/RoundRobinGroup.csproj
new file mode 100644
index 0000000..37f1fbc
--- /dev/null
+++ b/examples/targets/Configuration API/RoundRobinGroup/Simple/RoundRobinGroup.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{67EE6098-74A6-456F-8D27-C0D38D0A9B22}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>RoundRobinGroup</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/RoundRobinGroup/Simple/RoundRobinGroup.sln b/examples/targets/Configuration API/RoundRobinGroup/Simple/RoundRobinGroup.sln
new file mode 100644
index 0000000..d4f1a28
--- /dev/null
+++ b/examples/targets/Configuration API/RoundRobinGroup/Simple/RoundRobinGroup.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RoundRobinGroup", "RoundRobinGroup.csproj", "{67EE6098-74A6-456F-8D27-C0D38D0A9B22}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {67EE6098-74A6-456F-8D27-C0D38D0A9B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {67EE6098-74A6-456F-8D27-C0D38D0A9B22}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {67EE6098-74A6-456F-8D27-C0D38D0A9B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {67EE6098-74A6-456F-8D27-C0D38D0A9B22}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/SplitGroup/Simple/Example.cs b/examples/targets/Configuration API/SplitGroup/Simple/Example.cs
new file mode 100644
index 0000000..a8e62bd
--- /dev/null
+++ b/examples/targets/Configuration API/SplitGroup/Simple/Example.cs
@@ -0,0 +1,27 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using NLog.Targets.Compound;
+using System.Diagnostics;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ FileTarget file1 = new FileTarget();
+ file1.FileName = "${basedir}/file1.txt";
+
+ FileTarget file2 = new FileTarget();
+ file2.FileName = "${basedir}/file2.txt";
+
+ SplitTarget target = new SplitTarget();
+ target.Targets.Add(file1);
+ target.Targets.Add(file2);
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/SplitGroup/Simple/SplitGroup.csproj b/examples/targets/Configuration API/SplitGroup/Simple/SplitGroup.csproj
new file mode 100644
index 0000000..55f71fc
--- /dev/null
+++ b/examples/targets/Configuration API/SplitGroup/Simple/SplitGroup.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{6C8815D6-62F5-4DED-AE3F-0AF4D0178CDB}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>SplitGroup</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/SplitGroup/Simple/SplitGroup.sln b/examples/targets/Configuration API/SplitGroup/Simple/SplitGroup.sln
new file mode 100644
index 0000000..4a8f711
--- /dev/null
+++ b/examples/targets/Configuration API/SplitGroup/Simple/SplitGroup.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SplitGroup", "SplitGroup.csproj", "{6C8815D6-62F5-4DED-AE3F-0AF4D0178CDB}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6C8815D6-62F5-4DED-AE3F-0AF4D0178CDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6C8815D6-62F5-4DED-AE3F-0AF4D0178CDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6C8815D6-62F5-4DED-AE3F-0AF4D0178CDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6C8815D6-62F5-4DED-AE3F-0AF4D0178CDB}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Template.csproj b/examples/targets/Configuration API/Template.csproj
new file mode 100644
index 0000000..003a152
--- /dev/null
+++ b/examples/targets/Configuration API/Template.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{_PROJECT_GUID_}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>_PROJECT_NAME_</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/Template.sln b/examples/targets/Configuration API/Template.sln
new file mode 100644
index 0000000..624d741
--- /dev/null
+++ b/examples/targets/Configuration API/Template.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "_PROJECT_NAME_", "_PROJECT_NAME_.csproj", "{_PROJECT_GUID_}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {_PROJECT_GUID_}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {_PROJECT_GUID_}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {_PROJECT_GUID_}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {_PROJECT_GUID_}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/Trace/Simple/Example.cs b/examples/targets/Configuration API/Trace/Simple/Example.cs
new file mode 100644
index 0000000..cd5b6ee
--- /dev/null
+++ b/examples/targets/Configuration API/Trace/Simple/Example.cs
@@ -0,0 +1,21 @@
+using System;
+
+using NLog;
+using NLog.Targets;
+using System.Diagnostics;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ Trace.Listeners.Add(new ConsoleTraceListener());
+
+ TraceTarget target = new TraceTarget();
+ target.Layout = "${message}";
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Debug("log message");
+ }
+}
diff --git a/examples/targets/Configuration API/Trace/Simple/Trace.csproj b/examples/targets/Configuration API/Trace/Simple/Trace.csproj
new file mode 100644
index 0000000..38cc287
--- /dev/null
+++ b/examples/targets/Configuration API/Trace/Simple/Trace.csproj
@@ -0,0 +1,40 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{DE02AB34-33D1-42CA-A3F0-68F4B1BF98B1}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Trace</AssemblyName>
+ <RootNamespace>
+ </RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/Trace/Simple/Trace.sln b/examples/targets/Configuration API/Trace/Simple/Trace.sln
new file mode 100644
index 0000000..49668db
--- /dev/null
+++ b/examples/targets/Configuration API/Trace/Simple/Trace.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Trace", "Trace.csproj", "{DE02AB34-33D1-42CA-A3F0-68F4B1BF98B1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {DE02AB34-33D1-42CA-A3F0-68F4B1BF98B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DE02AB34-33D1-42CA-A3F0-68F4B1BF98B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DE02AB34-33D1-42CA-A3F0-68F4B1BF98B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DE02AB34-33D1-42CA-A3F0-68F4B1BF98B1}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/WebService/Simple/Example.cs b/examples/targets/Configuration API/WebService/Simple/Example.cs
new file mode 100644
index 0000000..bd540df
--- /dev/null
+++ b/examples/targets/Configuration API/WebService/Simple/Example.cs
@@ -0,0 +1,28 @@
+using NLog;
+using NLog.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ WebServiceTarget target = new WebServiceTarget();
+ target.Url = "http://localhost:2648/Service1.asmx";
+ target.MethodName = "HelloWorld";
+ target.Namespace = "http://www.nlog-project.org/example";
+ target.Protocol = WebServiceTarget.WebServiceProtocol.Soap11;
+
+ target.Parameters.Add(new MethodCallParameter("n1", "${message}"));
+ target.Parameters.Add(new MethodCallParameter("n2", "${logger}"));
+ target.Parameters.Add(new MethodCallParameter("n3", "${level}"));
+
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Trace("log message 1");
+ logger.Debug("log message 2");
+ logger.Info("log message 3");
+ logger.Warn("log message 4");
+ logger.Error("log message 5");
+ logger.Fatal("log message 6");
+ }
+}
diff --git a/examples/targets/Configuration API/WebService/Simple/WebService.csproj b/examples/targets/Configuration API/WebService/Simple/WebService.csproj
new file mode 100644
index 0000000..553cdc7
--- /dev/null
+++ b/examples/targets/Configuration API/WebService/Simple/WebService.csproj
@@ -0,0 +1,39 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{70F18C83-2063-4D7F-96A9-4B1DA6752C95}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>WebService</AssemblyName>
+ <RootNamespace></RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="NLog">
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Example.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
diff --git a/examples/targets/Configuration API/WebService/Simple/WebService.sln b/examples/targets/Configuration API/WebService/Simple/WebService.sln
new file mode 100644
index 0000000..21babcf
--- /dev/null
+++ b/examples/targets/Configuration API/WebService/Simple/WebService.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebService", "WebService.csproj", "{70F18C83-2063-4D7F-96A9-4B1DA6752C95}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebService1", "WebService1\WebService1.csproj", "{7E750696-C0EC-4B2C-B870-331A54F25CA4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {70F18C83-2063-4D7F-96A9-4B1DA6752C95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {70F18C83-2063-4D7F-96A9-4B1DA6752C95}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {70F18C83-2063-4D7F-96A9-4B1DA6752C95}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {70F18C83-2063-4D7F-96A9-4B1DA6752C95}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7E750696-C0EC-4B2C-B870-331A54F25CA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7E750696-C0EC-4B2C-B870-331A54F25CA4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7E750696-C0EC-4B2C-B870-331A54F25CA4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7E750696-C0EC-4B2C-B870-331A54F25CA4}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Configuration API/WebService/Simple/WebService1/Properties/AssemblyInfo.cs b/examples/targets/Configuration API/WebService/Simple/WebService1/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..228b2fc
--- /dev/null
+++ b/examples/targets/Configuration API/WebService/Simple/WebService1/Properties/AssemblyInfo.cs
@@ -0,0 +1,13 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("WebService1")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: ComVisible(false)]
+[assembly: Guid("3d5900ae-111a-45be-96b3-d9e4606ca793")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/examples/targets/Configuration API/WebService/Simple/WebService1/Service1.asmx b/examples/targets/Configuration API/WebService/Simple/WebService1/Service1.asmx
new file mode 100644
index 0000000..78a6aa0
--- /dev/null
+++ b/examples/targets/Configuration API/WebService/Simple/WebService1/Service1.asmx
@@ -0,0 +1 @@
+<%@ WebService Language="C#" CodeBehind="Service1.asmx.cs" Class="WebService1.Service1" %>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/WebService/Simple/WebService1/Service1.asmx.cs b/examples/targets/Configuration API/WebService/Simple/WebService1/Service1.asmx.cs
new file mode 100644
index 0000000..318fe1a
--- /dev/null
+++ b/examples/targets/Configuration API/WebService/Simple/WebService1/Service1.asmx.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Data;
+using System.Web;
+using System.Collections;
+using System.Web.Services;
+using System.Web.Services.Protocols;
+using System.ComponentModel;
+
+namespace WebService1
+{
+ [WebService(Namespace = "http://www.nlog-project.org/example")]
+ [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
+ [ToolboxItem(false)]
+ public class Service1 : System.Web.Services.WebService
+ {
+ [WebMethod]
+ public void HelloWorld(string n1, string n2, string n3)
+ {
+ HttpContext.Current.Trace.Write("n1 " + n1);
+ HttpContext.Current.Trace.Write("n2 " + n2);
+ HttpContext.Current.Trace.Write("n3 " + n3);
+ }
+ }
+}
diff --git a/examples/targets/Configuration API/WebService/Simple/WebService1/Web.config b/examples/targets/Configuration API/WebService/Simple/WebService1/Web.config
new file mode 100644
index 0000000..777d465
--- /dev/null
+++ b/examples/targets/Configuration API/WebService/Simple/WebService1/Web.config
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+
+<configuration>
+
+ <appSettings/>
+ <connectionStrings/>
+
+ <system.web>
+ <!--
+ Set compilation debug="true" to insert debugging
+ symbols into the compiled page. Because this
+ affects performance, set this value to true only
+ during development.
+ -->
+ <compilation debug="true" />
+ <!--
+ The <authentication> section enables configuration
+ of the security authentication mode used by
+ ASP.NET to identify an incoming user.
+ -->
+ <trace enabled="true"/>
+ <authentication mode="Windows" />
+ <!--
+ The <customErrors> section enables configuration
+ of what to do if/when an unhandled error occurs
+ during the execution of a request. Specifically,
+ it enables developers to configure html error pages
+ to be displayed in place of a error stack trace.
+
+ <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
+ <error statusCode="403" redirect="NoAccess.htm" />
+ <error statusCode="404" redirect="FileNotFound.htm" />
+ </customErrors>
+ -->
+ </system.web>
+</configuration>
diff --git a/examples/targets/Configuration API/WebService/Simple/WebService1/WebService1.csproj b/examples/targets/Configuration API/WebService/Simple/WebService1/WebService1.csproj
new file mode 100644
index 0000000..7a8c887
--- /dev/null
+++ b/examples/targets/Configuration API/WebService/Simple/WebService1/WebService1.csproj
@@ -0,0 +1,77 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{7E750696-C0EC-4B2C-B870-331A54F25CA4}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>WebService1</RootNamespace>
+ <AssemblyName>WebService1</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="System.Web.Mobile" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Service1.asmx" />
+ <Content Include="Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Service1.asmx.cs">
+ <DependentUpon>Service1.asmx</DependentUpon>
+ <SubType>Component</SubType>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v8.0\WebApplications\Microsoft.WebApplication.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>False</UseIIS>
+ <AutoAssignPort>True</AutoAssignPort>
+ <DevelopmentServerPort>2648</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>
+ </IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration API/makeproject.pl b/examples/targets/Configuration API/makeproject.pl
new file mode 100644
index 0000000..81a5194
--- /dev/null
+++ b/examples/targets/Configuration API/makeproject.pl
@@ -0,0 +1,37 @@
+my $targetName = shift || die;
+my $variantName = shift;
+my $projectGuid = `uuidgen -c`;
+my $projectName = "$targetName.$variantName";
+my $projectDir = "$targetName/$variantName";
+
+if ($variantName eq "")
+{
+ $projectDir = "$targetName/Simple";
+ $projectName = "$targetName";
+}
+chomp $projectGuid;
+
+sub apply_template
+{
+ my $src = shift || die;
+ my $dst = shift || die;
+
+ open(IN, "<$src") || die;
+ open(OUT, ">$dst") || die;
+ while (<IN>)
+ {
+ s/_TARGET_/$targetName/g;
+ s/_VARIANT_/$variantName/g;
+ s/_PROJECT_GUID_/$projectGuid/g;
+ s/_PROJECT_NAME_/$projectName/g;
+ s/_PROJECT_DIR_/$projectDir/g;
+ print OUT;
+ }
+ close(OUT);
+ close(IN);
+}
+
+mkdir("$targetName",0666);
+mkdir("$projectDir",0666);
+apply_template("Template.sln", "$projectDir/$projectName.sln");
+apply_template("Template.csproj", "$projectDir/$projectName.csproj");
diff --git a/examples/targets/Configuration File/ASPNetBufferingWrapper/web.nlog b/examples/targets/Configuration File/ASPNetBufferingWrapper/web.nlog
new file mode 100644
index 0000000..ee613c0
--- /dev/null
+++ b/examples/targets/Configuration File/ASPNetBufferingWrapper/web.nlog
@@ -0,0 +1,15 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="t" xsi:type="ASPNetBufferingWrapper">
+ <target xsi:type="PostFilteringWrapper" defaultFilter="level >= LogLevel.Info">
+ <target xsi:type="File" fileName="${basedir}/file.txt"/>
+ <when exists="level >= LogLevel.Warn" filter="level >= LogLevel.Debug"/>
+ </target>
+ </target>
+ </targets>
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="t" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/ASPNetTrace/web.nlog b/examples/targets/Configuration File/ASPNetTrace/web.nlog
new file mode 100644
index 0000000..e960b9b
--- /dev/null
+++ b/examples/targets/Configuration File/ASPNetTrace/web.nlog
@@ -0,0 +1,10 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="aspnet" xsi:type="ASPNetTrace" layout="${logger} ${message}" />
+ </targets>
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="aspnet" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/AsyncWrapper/NLog.config b/examples/targets/Configuration File/AsyncWrapper/NLog.config
new file mode 100644
index 0000000..c5ebee8
--- /dev/null
+++ b/examples/targets/Configuration File/AsyncWrapper/NLog.config
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <!-- Log in a separate thread, possibly queueing up to
+ 5000 messages. When the queue overflows, discard any
+ extra messages-->
+
+ <target name="file" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
+ <target xsi:type="File" fileName="${basedir}/logs/${level}.txt" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/AutoFlushWrapper/NLog.config b/examples/targets/Configuration File/AutoFlushWrapper/NLog.config
new file mode 100644
index 0000000..680ab07
--- /dev/null
+++ b/examples/targets/Configuration File/AutoFlushWrapper/NLog.config
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="file" xsi:type="AutoFlushWrapper">
+ <target xsi:type="File" fileName="${basedir}/file.txt" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/BufferingWrapper/NLog.config b/examples/targets/Configuration File/BufferingWrapper/NLog.config
new file mode 100644
index 0000000..873d84a
--- /dev/null
+++ b/examples/targets/Configuration File/BufferingWrapper/NLog.config
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="file" xsi:type="BufferingWrapper" bufferSize="100">
+ <target xsi:type="File" fileName="${basedir}/file.txt" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/Chainsaw/NLog.config b/examples/targets/Configuration File/Chainsaw/NLog.config
new file mode 100644
index 0000000..c9d90d6
--- /dev/null
+++ b/examples/targets/Configuration File/Chainsaw/NLog.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="viewer" xsi:type="Chainsaw" address="ucp://localhost:4000" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="viewer" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/ColoredConsole/Row Highlighting/NLog.config b/examples/targets/Configuration File/ColoredConsole/Row Highlighting/NLog.config
new file mode 100644
index 0000000..cc4711f
--- /dev/null
+++ b/examples/targets/Configuration File/ColoredConsole/Row Highlighting/NLog.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="console" xsi:type="ColoredConsole" layout="${date:format=HH\:MM\:ss} ${logger} ${message}">
+ <highlight-row condition="level >= LogLevel.Error and contains(message,'serious')" foregroundColor="White" backgroundColor="Red" />
+ <highlight-row condition="starts-with(logger,'Example')" foregroundColor="Yellow" backgroundColor="DarkBlue" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Trace" writeTo="console" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/ColoredConsole/Simple/NLog.config b/examples/targets/Configuration File/ColoredConsole/Simple/NLog.config
new file mode 100644
index 0000000..599de68
--- /dev/null
+++ b/examples/targets/Configuration File/ColoredConsole/Simple/NLog.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="console" xsi:type="ColoredConsole" layout="${date:format=HH\:MM\:ss} ${logger} ${message}">
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Trace" writeTo="console" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/ColoredConsole/Word Highlighting/NLog.config b/examples/targets/Configuration File/ColoredConsole/Word Highlighting/NLog.config
new file mode 100644
index 0000000..7615c7b
--- /dev/null
+++ b/examples/targets/Configuration File/ColoredConsole/Word Highlighting/NLog.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="console" xsi:type="ColoredConsole" layout="${date:format=HH\:MM\:ss} ${logger} ${message}">
+ <highlight-word text="log" backgroundColor="DarkGreen" />
+ <highlight-word text="abc" foregroundColor="Cyan" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Trace" writeTo="console" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/Console/NLog.config b/examples/targets/Configuration File/Console/NLog.config
new file mode 100644
index 0000000..bc31ad9
--- /dev/null
+++ b/examples/targets/Configuration File/Console/NLog.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="console" xsi:type="Console" layout="${date:format=HH\:MM\:ss} ${logger} ${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Info" writeTo="console" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/Database/MSSQL/NLog.config b/examples/targets/Configuration File/Database/MSSQL/NLog.config
new file mode 100644
index 0000000..edf9371
--- /dev/null
+++ b/examples/targets/Configuration File/Database/MSSQL/NLog.config
@@ -0,0 +1,30 @@
+<?xml version="1.0" ?>
+<nlog autoReload="true">
+ <targets>
+ <target name="database" type="Database">
+
+ <dbprovider>mssql</dbprovider>
+
+ <!-- database connection parameters -->
+ <!-- alternatively you could provide a single 'connectionstring' parameter -->
+
+ <dbhost>.</dbhost>
+ <dbdatabase>NLogDatabase</dbdatabase>
+ <dbusername>nloguser</dbusername>
+ <dbpassword>nlogpassword</dbpassword>
+
+ <commandText>
+ insert into LogTable(time_stamp,level,logger,message) values(@time_stamp, @level, @logger, @message);
+ </commandText>
+
+ <parameter name="@time_stamp" layout="${date}" />
+ <parameter name="@level" layout="${level}" />
+ <parameter name="@logger" layout="${logger}" />
+ <parameter name="@message" layout="${message}" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" appendTo="database" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/Database/MSSQL/create_nlog_database.bat b/examples/targets/Configuration File/Database/MSSQL/create_nlog_database.bat
new file mode 100644
index 0000000..7b3bfb1
--- /dev/null
+++ b/examples/targets/Configuration File/Database/MSSQL/create_nlog_database.bat
@@ -0,0 +1,21 @@
+ at echo off
+set DBNAME=NLogDatabase
+if (%1)==() goto usage
+set LOGIN=
+if (%2)==() set LOGIN=-E
+cls
+echo.
+echo This will create %DBNAME% database on %1
+echo.
+echo You can press Ctrl+C to quit now.
+echo.
+pause
+osql -S %1 %LOGIN% %2 %3 %4 %5 %6 -n -i create_nlog_database.sql
+pause
+goto quit
+
+:usage
+echo Usage: create_nlog_database.bat HOSTNAME
+echo This will create %DBNAME% database on HOSTNAME
+
+:quit
diff --git a/examples/targets/Configuration File/Database/MSSQL/create_nlog_database.sql b/examples/targets/Configuration File/Database/MSSQL/create_nlog_database.sql
new file mode 100644
index 0000000..a605925
--- /dev/null
+++ b/examples/targets/Configuration File/Database/MSSQL/create_nlog_database.sql
@@ -0,0 +1,35 @@
+use master;
+go
+
+create database NLogDatabase
+/*
+on primary (name='NLogDatabase
+filename='***insert_path_here***\NLogDatabase.mdf',
+size=10MB)
+log on (name='NLogDatabase_log',
+filename='***insert_path_here***\NLogDatabase_log.ldf',
+size=10MB)
+*/
+go
+
+exec sp_addlogin 'nloguser','nlogpassword',NLogDatabase
+go
+
+use NLogDatabase;
+go
+
+create table LogTable
+(
+ sequence_id integer not null primary key identity(1,1),
+ time_stamp datetime not null,
+ level varchar(5) not null,
+ logger varchar(80) not null,
+ message varchar(4095) not null,
+)
+go
+
+exec sp_grantdbaccess 'nloguser','nloguser'
+go
+
+grant insert,select on LogTable to nloguser
+go
diff --git a/examples/targets/Configuration File/Database/MSSQL/drop_nlog_database.bat b/examples/targets/Configuration File/Database/MSSQL/drop_nlog_database.bat
new file mode 100644
index 0000000..8b126b3
--- /dev/null
+++ b/examples/targets/Configuration File/Database/MSSQL/drop_nlog_database.bat
@@ -0,0 +1,19 @@
+ at echo off
+set DBNAME=NLogDatabase
+if (%1)==() goto usage
+cls
+echo.
+echo This will drop %DBNAME% database on %1
+echo.
+echo You can press Ctrl+C to quit now.
+echo.
+pause
+osql -S %1 -E -n -i drop_nlog_database.sql
+pause
+goto quit
+
+:usage
+echo Usage: drop_nlog_database.bat HOSTNAME
+echo This will drop %DBNAME% database on HOSTNAME
+
+:quit
diff --git a/examples/targets/Configuration File/Database/MSSQL/drop_nlog_database.sql b/examples/targets/Configuration File/Database/MSSQL/drop_nlog_database.sql
new file mode 100644
index 0000000..3837a07
--- /dev/null
+++ b/examples/targets/Configuration File/Database/MSSQL/drop_nlog_database.sql
@@ -0,0 +1,4 @@
+drop database NLogDatabase
+go
+exec sp_droplogin 'nloguser'
+go
diff --git a/examples/targets/Configuration File/Database/Oracle.Native/NLog.config b/examples/targets/Configuration File/Database/Oracle.Native/NLog.config
new file mode 100644
index 0000000..7b9c28f
--- /dev/null
+++ b/examples/targets/Configuration File/Database/Oracle.Native/NLog.config
@@ -0,0 +1,23 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <!-- configuration contributed by David Maly -->
+
+ <targets>
+ <target name="database" xsi:type="Database" keepConnection="false" useTransactions="true"
+ dbProvider="System.Data.OracleClient.OracleConnection,System.Data.OracleClient, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
+ connectionString="Data Source=MYORACLEDB;User Id=DBO;Password=MYPASSWORD;Integrated Security=no;"
+ commandText="insert into LOGTABLE( TIME_STAMP,LOGLEVEL,LOGGER,CALLSITE,MESSAGE) values( :TIME_STAMP,:LOGLEVEL,:LOGGER,:CALLSITE,:MESSAGE)">
+ <parameter name="TIME_STAMP" layout="${longdate}" />
+ <parameter name="LOGLEVEL" layout="${level:uppercase=true}" />
+ <parameter name="LOGGER" layout="${logger}" />
+ <parameter name="CALLSITE" layout="${callsite:filename=true}" />
+ <parameter name="MESSAGE" layout="${message}" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="database" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/Database/Oracle.OleDb/NLog.config b/examples/targets/Configuration File/Database/Oracle.OleDb/NLog.config
new file mode 100644
index 0000000..3800fc9
--- /dev/null
+++ b/examples/targets/Configuration File/Database/Oracle.OleDb/NLog.config
@@ -0,0 +1,22 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <!-- configuration contributed by David Maly -->
+
+ <targets>
+ <target name="database" xsi:type="Database" keepConnection="false" useTransactions="true" dbProvider="oledb"
+ connectionString="Provider=msdaora;Data Source=MYORACLEDB;User Id=DBO;Password=MYPASSWORD;"
+ commandText="insert into LOGTABLE( TIME_STAMP,LOGLEVEL,LOGGER,CALLSITE,MESSAGE) values(?,?,?,?,?)">
+ <parameter name="TIME_STAMP" layout="${longdate}" />
+ <parameter name="LOGLEVEL" layout="${level:uppercase=true}" />
+ <parameter name="LOGGER" layout="${logger}" />
+ <parameter name="CALLSITE" layout="${callsite:filename=true}" />
+ <parameter name="MESSAGE" layout="${message}" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="database" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/Debug/NLog.config b/examples/targets/Configuration File/Debug/NLog.config
new file mode 100644
index 0000000..7efaa70
--- /dev/null
+++ b/examples/targets/Configuration File/Debug/NLog.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="debug" xsi:type="Debug" layout="${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Info" writeTo="debug" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/Debugger/NLog.config b/examples/targets/Configuration File/Debugger/NLog.config
new file mode 100644
index 0000000..287acca
--- /dev/null
+++ b/examples/targets/Configuration File/Debugger/NLog.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="debugger" xsi:type="Debugger" layout="${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Info" writeTo="debugger" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/EventLog/NLog.config b/examples/targets/Configuration File/EventLog/NLog.config
new file mode 100644
index 0000000..860068f
--- /dev/null
+++ b/examples/targets/Configuration File/EventLog/NLog.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="eventlog" xsi:type="EventLog" layout="${logger}: ${message}" source="My Source" log="Application" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="eventlog" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/FallbackGroup/NLog.config b/examples/targets/Configuration File/FallbackGroup/NLog.config
new file mode 100644
index 0000000..1774fcf
--- /dev/null
+++ b/examples/targets/Configuration File/FallbackGroup/NLog.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="file" xsi:type="FallbackGroup" returnToFirstOnSuccess="false">
+ <target xsi:type="File" fileName="\\server1\share\file1.txt" />
+ <target xsi:type="File" fileName="\\server2\share\file1.txt" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/File/Archive1/NLog.config b/examples/targets/Configuration File/File/Archive1/NLog.config
new file mode 100644
index 0000000..1c0bd5e
--- /dev/null
+++ b/examples/targets/Configuration File/File/Archive1/NLog.config
@@ -0,0 +1,20 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="file" xsi:type="File"
+ layout="${longdate} ${logger} ${message}"
+ fileName="${basedir}/logs/logfile.txt"
+ archiveFileName="${basedir}/archives/log.{#####}.txt"
+ archiveAboveSize="10240"
+ archiveNumbering="Sequence"
+ concurrentWrites="true"
+ keepFileOpen="false"
+ encoding="iso-8859-2" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/File/Archive2/NLog.config b/examples/targets/Configuration File/File/Archive2/NLog.config
new file mode 100644
index 0000000..4049575
--- /dev/null
+++ b/examples/targets/Configuration File/File/Archive2/NLog.config
@@ -0,0 +1,20 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="file" xsi:type="File"
+ layout="${longdate} ${logger} ${message}"
+ fileName="${basedir}/logs/logfile.txt"
+ archiveFileName="${basedir}/archives/log.{#####}.txt"
+ archiveEvery="Minute"
+ archiveNumbering="Rolling"
+ concurrentWrites="true"
+ keepFileOpen="false"
+ encoding="iso-8859-2" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/File/Archive3/NLog.config b/examples/targets/Configuration File/File/Archive3/NLog.config
new file mode 100644
index 0000000..ff52776
--- /dev/null
+++ b/examples/targets/Configuration File/File/Archive3/NLog.config
@@ -0,0 +1,22 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="file" xsi:type="File"
+ layout="${longdate} ${logger} ${message}"
+ fileName="${basedir}/logs/logfile.txt"
+ archiveFileName="${basedir}/archives/log.{#####}.txt"
+ archiveEvery="Minute"
+ archiveAboveSize="10000"
+ archiveNumbering="Rolling"
+ maxArchiveFiles="3"
+ concurrentWrites="true"
+ keepFileOpen="false"
+ encoding="iso-8859-2" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/File/Archive4/NLog.config b/examples/targets/Configuration File/File/Archive4/NLog.config
new file mode 100644
index 0000000..9ac5a7c
--- /dev/null
+++ b/examples/targets/Configuration File/File/Archive4/NLog.config
@@ -0,0 +1,22 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="file" xsi:type="File"
+ layout="${longdate} ${logger} ${message}"
+ fileName="${basedir}/logs/logfile.${level}.txt"
+ archiveFileName="${basedir}/archives/${level}/log.{#####}.txt"
+ archiveEvery="Minute"
+ archiveAboveSize="10000"
+ archiveNumbering="Rolling"
+ maxArchiveFiles="3"
+ concurrentWrites="true"
+ keepFileOpen="false"
+ encoding="iso-8859-2" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/File/Asynchronous/NLog.config b/examples/targets/Configuration File/File/Asynchronous/NLog.config
new file mode 100644
index 0000000..e0f8bf0
--- /dev/null
+++ b/examples/targets/Configuration File/File/Asynchronous/NLog.config
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <!-- Log in a separate thread, possibly queueing up to
+ 5000 messages. When the queue overflows, discard any
+ extra messages-->
+
+ <target name="file" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
+ <target xsi:type="File" fileName="${basedir}/logs/${level}.txt" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/File/CSV/NLog.config b/examples/targets/Configuration File/File/CSV/NLog.config
new file mode 100644
index 0000000..7c74d1f
--- /dev/null
+++ b/examples/targets/Configuration File/File/CSV/NLog.config
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="csv" xsi:type="File" fileName="${basedir}/file.csv">
+ <layout xsi:type="CSVLayout">
+ <column name="time" layout="${longdate}" />
+ <column name="message" layout="${message}" />
+ <column name="logger" layout="${logger}"/>
+ <column name="level" layout="${level}"/>
+ </layout>
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="csv" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/File/Multiple/NLog.config b/examples/targets/Configuration File/File/Multiple/NLog.config
new file mode 100644
index 0000000..f30f1cb
--- /dev/null
+++ b/examples/targets/Configuration File/File/Multiple/NLog.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="file" xsi:type="File"
+ layout="${longdate} ${logger} ${message}"
+ fileName="${basedir}/${level}.log" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/File/Multiple2/NLog.config b/examples/targets/Configuration File/File/Multiple2/NLog.config
new file mode 100644
index 0000000..90a419d
--- /dev/null
+++ b/examples/targets/Configuration File/File/Multiple2/NLog.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="file" xsi:type="File"
+ layout="${longdate} ${logger} ${message}"
+ fileName="${basedir}/${shortdate}/${windows-identity:domain=false}.${level}.log" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/File/Simple/NLog.config b/examples/targets/Configuration File/File/Simple/NLog.config
new file mode 100644
index 0000000..d76abdb
--- /dev/null
+++ b/examples/targets/Configuration File/File/Simple/NLog.config
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="file" xsi:type="File"
+ layout="${longdate} ${logger} ${message}"
+ fileName="${basedir}/logs/logfile.txt"
+ keepFileOpen="false"
+ encoding="iso-8859-2" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/FilteringWrapper/NLog.config b/examples/targets/Configuration File/FilteringWrapper/NLog.config
new file mode 100644
index 0000000..f5b651f
--- /dev/null
+++ b/examples/targets/Configuration File/FilteringWrapper/NLog.config
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="file" xsi:type="FilteringWrapper" condition="contains('${message}','1')">
+ <target xsi:type="File" fileName="${basedir}/file.txt" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/FormControl/NLog.config b/examples/targets/Configuration File/FormControl/NLog.config
new file mode 100644
index 0000000..4a1860f
--- /dev/null
+++ b/examples/targets/Configuration File/FormControl/NLog.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="control" xsi:type="FormControl" append="true" controlName="textBox1" formName="Form1" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="control" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/MSMQ/Multiple/NLog.config b/examples/targets/Configuration File/MSMQ/Multiple/NLog.config
new file mode 100644
index 0000000..3c7af74
--- /dev/null
+++ b/examples/targets/Configuration File/MSMQ/Multiple/NLog.config
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="queue" xsi:type="MSMQ"
+ layout="${message}"
+ queue=".\private$\nlog.${logger}"
+ encoding="iso-8859-2"
+ recoverable="true"
+ label="${logger}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="queue" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/MSMQ/Simple/NLog.config b/examples/targets/Configuration File/MSMQ/Simple/NLog.config
new file mode 100644
index 0000000..ab9cbd1
--- /dev/null
+++ b/examples/targets/Configuration File/MSMQ/Simple/NLog.config
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="queue" xsi:type="MSMQ"
+ layout="${message}"
+ queue=".\private$\nlog"
+ encoding="iso-8859-2"
+ recoverable="true"
+ label="${logger}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="queue" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/Mail/Buffered/NLog.config b/examples/targets/Configuration File/Mail/Buffered/NLog.config
new file mode 100644
index 0000000..ff1bc2d
--- /dev/null
+++ b/examples/targets/Configuration File/Mail/Buffered/NLog.config
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="mail" xsi:type="BufferingWrapper" bufferSize="5">
+ <target xsi:type="Mail"
+ smtpServer="192.168.0.15"
+ from="jaak at jkowalski.net"
+ to="jaak at jkowalski.net"
+ subject="test subject" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="mail" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/Mail/Simple/NLog.config b/examples/targets/Configuration File/Mail/Simple/NLog.config
new file mode 100644
index 0000000..aa4260a
--- /dev/null
+++ b/examples/targets/Configuration File/Mail/Simple/NLog.config
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="mail" xsi:type="Mail"
+ smtpServer="192.168.0.15"
+ from="jaak at jkowalski.net"
+ to="jaak at jkowalski.net"
+ subject="test subject" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="mail" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/Memory/NLog.config b/examples/targets/Configuration File/Memory/NLog.config
new file mode 100644
index 0000000..a1f9381
--- /dev/null
+++ b/examples/targets/Configuration File/Memory/NLog.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="memory" xsi:type="Memory" layout="${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Info" writeTo="memory" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/MessageBox/NLog.config b/examples/targets/Configuration File/MessageBox/NLog.config
new file mode 100644
index 0000000..7dd46be
--- /dev/null
+++ b/examples/targets/Configuration File/MessageBox/NLog.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="msgbox" xsi:type="MessageBox" layout="${longdate}: ${message}" caption="${level}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="msgbox" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/MethodCall/NLog.config b/examples/targets/Configuration File/MethodCall/NLog.config
new file mode 100644
index 0000000..940a350
--- /dev/null
+++ b/examples/targets/Configuration File/MethodCall/NLog.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="m" xsi:type="MethodCall" className="Example, MethodCall" methodName="LogMethod">
+ <parameter layout="${level}" />
+ <parameter layout="${message}" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="msgbox" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/NLogViewer/NLog.config b/examples/targets/Configuration File/NLogViewer/NLog.config
new file mode 100644
index 0000000..698f1e1
--- /dev/null
+++ b/examples/targets/Configuration File/NLogViewer/NLog.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="viewer" xsi:type="NLogViewer" address="ucp://localhost:4000" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="viewer" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/Network/NLog.config b/examples/targets/Configuration File/Network/NLog.config
new file mode 100644
index 0000000..56a1603
--- /dev/null
+++ b/examples/targets/Configuration File/Network/NLog.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="network" xsi:type="Network" address="tcp://localhost:5555" layout="${level} ${logger} ${message}${newline}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="network" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/Null/NLog.config b/examples/targets/Configuration File/Null/NLog.config
new file mode 100644
index 0000000..d6bcbd0
--- /dev/null
+++ b/examples/targets/Configuration File/Null/NLog.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="n" xsi:type="Null" layout="${message}" formatMessage="true" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="n" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/OutputDebugString/NLog.config b/examples/targets/Configuration File/OutputDebugString/NLog.config
new file mode 100644
index 0000000..7cd816f
--- /dev/null
+++ b/examples/targets/Configuration File/OutputDebugString/NLog.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="n" xsi:type="OutputDebugString" layout="${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="n" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/PerfCounter/NLog.config b/examples/targets/Configuration File/PerfCounter/NLog.config
new file mode 100644
index 0000000..4ed526a
--- /dev/null
+++ b/examples/targets/Configuration File/PerfCounter/NLog.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="pc" xsi:type="PerfCounter" categoryName="My category"
+ counterName="My counter" counterType="NumberOfItems32" instanceName="myInstance" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="pc" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/PostFilteringWrapper/NLog.config b/examples/targets/Configuration File/PostFilteringWrapper/NLog.config
new file mode 100644
index 0000000..df38e00
--- /dev/null
+++ b/examples/targets/Configuration File/PostFilteringWrapper/NLog.config
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="file" xsi:type="BufferingWrapper" bufferSize="100">
+ <target xsi:type="PostFilteringWrapper" defaultFilter="level >= LogLevel.Info">
+ <target xsi:type="File" fileName="${basedir}/file.txt" />
+ <when exists="level >= LogLevel.Warn" filter="level >= LogLevel.Debug"/>
+ </target>
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/RandomizeGroup/NLog.config b/examples/targets/Configuration File/RandomizeGroup/NLog.config
new file mode 100644
index 0000000..0755ade
--- /dev/null
+++ b/examples/targets/Configuration File/RandomizeGroup/NLog.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="file" xsi:type="RandomizeGroup">
+ <target xsi:type="File" fileName="${basedir}/file1.txt" />
+ <target xsi:type="File" fileName="${basedir}/file2.txt" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/RepeatingWrapper/NLog.config b/examples/targets/Configuration File/RepeatingWrapper/NLog.config
new file mode 100644
index 0000000..187741b
--- /dev/null
+++ b/examples/targets/Configuration File/RepeatingWrapper/NLog.config
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="file" xsi:type="RepeatingWrapper" repeatCount="3">
+ <target xsi:type="File" fileName="${basedir}/file.txt" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/RetryingWrapper/NLog.config b/examples/targets/Configuration File/RetryingWrapper/NLog.config
new file mode 100644
index 0000000..9fe4c8c
--- /dev/null
+++ b/examples/targets/Configuration File/RetryingWrapper/NLog.config
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="file" xsi:type="RetryingWrapper" retryCount="3" retryDelayMilliseconds="1000">
+ <target xsi:type="File" fileName="${basedir}/file.txt" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/RichTextBox/RowColoring/NLog.config b/examples/targets/Configuration File/RichTextBox/RowColoring/NLog.config
new file mode 100644
index 0000000..751af65
--- /dev/null
+++ b/examples/targets/Configuration File/RichTextBox/RowColoring/NLog.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="richTextBox" xsi:type="RichTextBox" controlName="richTextBox1" formName="form1" useDefaultRowColoringRules="true">
+ <row-coloring condition="contains(message,'serious')" fontColor="Red" backgroundColor="Blue" style="Underline,Italic" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="richTextBox" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/RichTextBox/Simple/NLog.config b/examples/targets/Configuration File/RichTextBox/Simple/NLog.config
new file mode 100644
index 0000000..190bcea
--- /dev/null
+++ b/examples/targets/Configuration File/RichTextBox/Simple/NLog.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="richTextBox" xsi:type="RichTextBox" controlName="richTextBox1" formName="form1" useDefaultRowColoringRules="false"/>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="richTextBox" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/RichTextBox/WordColoring/NLog.config b/examples/targets/Configuration File/RichTextBox/WordColoring/NLog.config
new file mode 100644
index 0000000..19f45dd
--- /dev/null
+++ b/examples/targets/Configuration File/RichTextBox/WordColoring/NLog.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="richTextBox" xsi:type="RichTextBox" controlName="richTextBox1" formName="form1" useDefaultRowColoringRules="true">
+ <word-coloring text="message" fontColor="Green" backgroundColor="Black"/>
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="richTextBox" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/RoundRobinGroup/NLog.config b/examples/targets/Configuration File/RoundRobinGroup/NLog.config
new file mode 100644
index 0000000..983c475
--- /dev/null
+++ b/examples/targets/Configuration File/RoundRobinGroup/NLog.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="file" xsi:type="RoundRobinGroup">
+ <target xsi:type="File" fileName="${basedir}/file1.txt" />
+ <target xsi:type="File" fileName="${basedir}/file2.txt" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/SplitGroup/NLog.config b/examples/targets/Configuration File/SplitGroup/NLog.config
new file mode 100644
index 0000000..b03f2e3
--- /dev/null
+++ b/examples/targets/Configuration File/SplitGroup/NLog.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="file" xsi:type="SplitGroup">
+ <target xsi:type="File" fileName="${basedir}/file1.txt" />
+ <target xsi:type="File" fileName="${basedir}/file2.txt" />
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/Trace/NLog.config b/examples/targets/Configuration File/Trace/NLog.config
new file mode 100644
index 0000000..69d88ba
--- /dev/null
+++ b/examples/targets/Configuration File/Trace/NLog.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="n" xsi:type="Trace" layout="${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="n" />
+ </rules>
+</nlog>
diff --git a/examples/targets/Configuration File/WebService/NLog.config b/examples/targets/Configuration File/WebService/NLog.config
new file mode 100644
index 0000000..80db39c
--- /dev/null
+++ b/examples/targets/Configuration File/WebService/NLog.config
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<nlog autoReload="true"
+ xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="ws" xsi:type="WebService" namespace="http://www.nlog-project.org/example" protocol="Soap11" methodName="HelloWorld" url="http://localhost:2648/Service1.asmx">
+ <parameter name="n1" type="System.String" layout="${message}"/>
+ <parameter name="n2" type="System.String" layout="${logger}"/>
+ <parameter name="n3" type="System.String" layout="${level}"/>
+ </target>
+ </targets>
+
+ <rules>
+ <logger name="*" writeTo="ws" />
+ </rules>
+</nlog>
+
diff --git a/examples/targets/Configuration File/WebService/WebService1/Properties/AssemblyInfo.cs b/examples/targets/Configuration File/WebService/WebService1/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..228b2fc
--- /dev/null
+++ b/examples/targets/Configuration File/WebService/WebService1/Properties/AssemblyInfo.cs
@@ -0,0 +1,13 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("WebService1")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: ComVisible(false)]
+[assembly: Guid("3d5900ae-111a-45be-96b3-d9e4606ca793")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/examples/targets/Configuration File/WebService/WebService1/Service1.asmx b/examples/targets/Configuration File/WebService/WebService1/Service1.asmx
new file mode 100644
index 0000000..78a6aa0
--- /dev/null
+++ b/examples/targets/Configuration File/WebService/WebService1/Service1.asmx
@@ -0,0 +1 @@
+<%@ WebService Language="C#" CodeBehind="Service1.asmx.cs" Class="WebService1.Service1" %>
\ No newline at end of file
diff --git a/examples/targets/Configuration File/WebService/WebService1/Service1.asmx.cs b/examples/targets/Configuration File/WebService/WebService1/Service1.asmx.cs
new file mode 100644
index 0000000..318fe1a
--- /dev/null
+++ b/examples/targets/Configuration File/WebService/WebService1/Service1.asmx.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Data;
+using System.Web;
+using System.Collections;
+using System.Web.Services;
+using System.Web.Services.Protocols;
+using System.ComponentModel;
+
+namespace WebService1
+{
+ [WebService(Namespace = "http://www.nlog-project.org/example")]
+ [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
+ [ToolboxItem(false)]
+ public class Service1 : System.Web.Services.WebService
+ {
+ [WebMethod]
+ public void HelloWorld(string n1, string n2, string n3)
+ {
+ HttpContext.Current.Trace.Write("n1 " + n1);
+ HttpContext.Current.Trace.Write("n2 " + n2);
+ HttpContext.Current.Trace.Write("n3 " + n3);
+ }
+ }
+}
diff --git a/examples/targets/Configuration File/WebService/WebService1/Web.config b/examples/targets/Configuration File/WebService/WebService1/Web.config
new file mode 100644
index 0000000..777d465
--- /dev/null
+++ b/examples/targets/Configuration File/WebService/WebService1/Web.config
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+
+<configuration>
+
+ <appSettings/>
+ <connectionStrings/>
+
+ <system.web>
+ <!--
+ Set compilation debug="true" to insert debugging
+ symbols into the compiled page. Because this
+ affects performance, set this value to true only
+ during development.
+ -->
+ <compilation debug="true" />
+ <!--
+ The <authentication> section enables configuration
+ of the security authentication mode used by
+ ASP.NET to identify an incoming user.
+ -->
+ <trace enabled="true"/>
+ <authentication mode="Windows" />
+ <!--
+ The <customErrors> section enables configuration
+ of what to do if/when an unhandled error occurs
+ during the execution of a request. Specifically,
+ it enables developers to configure html error pages
+ to be displayed in place of a error stack trace.
+
+ <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
+ <error statusCode="403" redirect="NoAccess.htm" />
+ <error statusCode="404" redirect="FileNotFound.htm" />
+ </customErrors>
+ -->
+ </system.web>
+</configuration>
diff --git a/examples/targets/Configuration File/WebService/WebService1/WebService1.csproj b/examples/targets/Configuration File/WebService/WebService1/WebService1.csproj
new file mode 100644
index 0000000..7a8c887
--- /dev/null
+++ b/examples/targets/Configuration File/WebService/WebService1/WebService1.csproj
@@ -0,0 +1,77 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{7E750696-C0EC-4B2C-B870-331A54F25CA4}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>WebService1</RootNamespace>
+ <AssemblyName>WebService1</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="System.Web.Mobile" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Service1.asmx" />
+ <Content Include="Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Service1.asmx.cs">
+ <DependentUpon>Service1.asmx</DependentUpon>
+ <SubType>Component</SubType>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v8.0\WebApplications\Microsoft.WebApplication.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>False</UseIIS>
+ <AutoAssignPort>True</AutoAssignPort>
+ <DevelopmentServerPort>2648</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>
+ </IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/examples/targets/Configuration File/WebService/WebService1/WebService1.sln b/examples/targets/Configuration File/WebService/WebService1/WebService1.sln
new file mode 100644
index 0000000..c759ff6
--- /dev/null
+++ b/examples/targets/Configuration File/WebService/WebService1/WebService1.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebService1", "WebService1.csproj", "{7E750696-C0EC-4B2C-B870-331A54F25CA4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7E750696-C0EC-4B2C-B870-331A54F25CA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7E750696-C0EC-4B2C-B870-331A54F25CA4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7E750696-C0EC-4B2C-B870-331A54F25CA4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7E750696-C0EC-4B2C-B870-331A54F25CA4}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/examples/targets/Screenshots/ASPNetTrace/ASPNetTraceOutput1.gif b/examples/targets/Screenshots/ASPNetTrace/ASPNetTraceOutput1.gif
new file mode 100644
index 0000000..462565b
Binary files /dev/null and b/examples/targets/Screenshots/ASPNetTrace/ASPNetTraceOutput1.gif differ
diff --git a/examples/targets/Screenshots/ASPNetTrace/ASPNetTraceOutput2.gif b/examples/targets/Screenshots/ASPNetTrace/ASPNetTraceOutput2.gif
new file mode 100644
index 0000000..719f808
Binary files /dev/null and b/examples/targets/Screenshots/ASPNetTrace/ASPNetTraceOutput2.gif differ
diff --git a/examples/targets/Screenshots/ColoredConsole/Row Highlighting.gif b/examples/targets/Screenshots/ColoredConsole/Row Highlighting.gif
new file mode 100644
index 0000000..1b25b6d
Binary files /dev/null and b/examples/targets/Screenshots/ColoredConsole/Row Highlighting.gif differ
diff --git a/examples/targets/Screenshots/ColoredConsole/Simple.gif b/examples/targets/Screenshots/ColoredConsole/Simple.gif
new file mode 100644
index 0000000..1dcd951
Binary files /dev/null and b/examples/targets/Screenshots/ColoredConsole/Simple.gif differ
diff --git a/examples/targets/Screenshots/ColoredConsole/Word Highlighting.gif b/examples/targets/Screenshots/ColoredConsole/Word Highlighting.gif
new file mode 100644
index 0000000..633fce7
Binary files /dev/null and b/examples/targets/Screenshots/ColoredConsole/Word Highlighting.gif differ
diff --git a/examples/targets/Screenshots/FormControl/FormControl.gif b/examples/targets/Screenshots/FormControl/FormControl.gif
new file mode 100644
index 0000000..83ce8b7
Binary files /dev/null and b/examples/targets/Screenshots/FormControl/FormControl.gif differ
diff --git a/examples/targets/Screenshots/MessageBox/MessageBoxTarget.gif b/examples/targets/Screenshots/MessageBox/MessageBoxTarget.gif
new file mode 100644
index 0000000..e8f8e5f
Binary files /dev/null and b/examples/targets/Screenshots/MessageBox/MessageBoxTarget.gif differ
diff --git a/examples/targets/Screenshots/Network/Output.gif b/examples/targets/Screenshots/Network/Output.gif
new file mode 100644
index 0000000..083861c
Binary files /dev/null and b/examples/targets/Screenshots/Network/Output.gif differ
diff --git a/examples/targets/Screenshots/RichTextBox/RowColoring.gif b/examples/targets/Screenshots/RichTextBox/RowColoring.gif
new file mode 100644
index 0000000..569e111
Binary files /dev/null and b/examples/targets/Screenshots/RichTextBox/RowColoring.gif differ
diff --git a/examples/targets/Screenshots/RichTextBox/Simple.gif b/examples/targets/Screenshots/RichTextBox/Simple.gif
new file mode 100644
index 0000000..1788698
Binary files /dev/null and b/examples/targets/Screenshots/RichTextBox/Simple.gif differ
diff --git a/examples/targets/Screenshots/RichTextBox/WordColoring.gif b/examples/targets/Screenshots/RichTextBox/WordColoring.gif
new file mode 100644
index 0000000..bd784aa
Binary files /dev/null and b/examples/targets/Screenshots/RichTextBox/WordColoring.gif differ
diff --git a/examples/web/AddFilter.cs b/examples/web/AddFilter.cs
new file mode 100644
index 0000000..21e7106
--- /dev/null
+++ b/examples/web/AddFilter.cs
@@ -0,0 +1,6 @@
+static void Main(string[] args)
+{
+ FilterFactory.AddFilter("MyFirst", typeof(MyNamespace.MyFirstFilter));
+
+ // start logging here
+}
diff --git a/examples/web/AddLayoutRenderer.cs b/examples/web/AddLayoutRenderer.cs
new file mode 100644
index 0000000..74beec7
--- /dev/null
+++ b/examples/web/AddLayoutRenderer.cs
@@ -0,0 +1,6 @@
+static void Main(string[] args)
+{
+ LayoutRendererFactory.AddLayoutRenderer("hour", typeof(MyNamespace.MyFirstLayoutRenderer));
+
+ // start logging here
+}
diff --git a/examples/web/AddTarget.cs b/examples/web/AddTarget.cs
new file mode 100644
index 0000000..c29f7f7
--- /dev/null
+++ b/examples/web/AddTarget.cs
@@ -0,0 +1,6 @@
+static void Main(string[] args)
+{
+ TargetFactory.AddTarget("MyFirst", typeof(MyNamespace.MyFirstTarget));
+
+ // start logging here
+}
diff --git a/examples/web/GetCurrentClassLogger.cs b/examples/web/GetCurrentClassLogger.cs
new file mode 100644
index 0000000..3fd561c
--- /dev/null
+++ b/examples/web/GetCurrentClassLogger.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Globalization;
+
+using NLog;
+
+class MyClass {
+ static Logger logger = LogManager.GetCurrentClassLogger();
+
+ // class members go here
+
+}
diff --git a/examples/web/GetLogger.cs b/examples/web/GetLogger.cs
new file mode 100644
index 0000000..55ecbda
--- /dev/null
+++ b/examples/web/GetLogger.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Globalization;
+
+using NLog;
+
+class MyClass {
+ static Logger logger = LogManager.GetLogger("MyClass");
+
+ // other class members go here
+
+}
diff --git a/examples/web/MyFirstFilter.cs b/examples/web/MyFirstFilter.cs
new file mode 100644
index 0000000..a2268d7
--- /dev/null
+++ b/examples/web/MyFirstFilter.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Text;
+
+using NLog;
+
+namespace MyNamespace
+{
+ [Filter("hourRange")]
+ public sealed class HourRangeFilter: Filter
+ {
+ private int _fromHour = 0;
+ private int _toHour = -1;
+
+ public int FromHour
+ {
+ get { return _fromHour; }
+ set { _fromHour = value; }
+
+ }
+ public int ToHour
+ {
+ get { return _toHour; }
+ set { _toHour = value; }
+
+ }
+
+ protected override FilterResult Check(LogEventInfo ev)
+ {
+ if (ev.TimeStamp.Hour >= FromHour && ev.TimeStamp.Hour <= ToHour)
+ return Result;
+ else
+ return FilterResult.Neutral;
+ }
+ }
+}
diff --git a/examples/web/MyFirstLayoutRenderer.cs b/examples/web/MyFirstLayoutRenderer.cs
new file mode 100644
index 0000000..67f69b3
--- /dev/null
+++ b/examples/web/MyFirstLayoutRenderer.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Text;
+
+using NLog;
+
+namespace MyNamespace
+{
+ [LayoutRenderer("hour")]
+ public sealed class HourLayoutRenderer: LayoutRenderer
+ {
+ private bool _showMinutes = false;
+
+ // this is an example of a configurable parameter
+ public bool ShowMinutes
+ {
+ get { return _showMinutes; }
+ set { _showMinutes = value; }
+
+ }
+ protected override int GetEstimatedBufferSize(LogEventInfo ev)
+ {
+ // since hour is expressed by 2 digits we need at most 2-character
+ // buffer for it
+ return 2;
+ }
+
+ protected override void Append(StringBuilder builder, LogEventInfo ev)
+ {
+ // get current hour or minute, convert it to string, apply padding
+ // and append to the specified StringBuilder
+ if (ShowMinutes)
+ {
+ builder.Append(ApplyPadding(DateTime.Now.Minute.ToString()));
+ }
+ else
+ {
+ builder.Append(ApplyPadding(DateTime.Now.Hour.ToString()));
+ }
+ }
+ }
+}
diff --git a/examples/web/MyFirstTarget.cs b/examples/web/MyFirstTarget.cs
new file mode 100644
index 0000000..b7513cd
--- /dev/null
+++ b/examples/web/MyFirstTarget.cs
@@ -0,0 +1,28 @@
+using NLog;
+
+namespace MyNamespace
+{
+ [Target("MyFirst")]
+ public sealed class MyFirstTarget: TargetWithLayout
+ {
+ private string _host = "localhost";
+
+ public string Host
+ {
+ get { return _host; }
+ set { _host = value; }
+ }
+
+ protected override void Write(LogEventInfo logEvent)
+ {
+ string logMessage = CompiledLayout.GetFormattedMessage(logEvent);
+
+ SendTheMessageToRemoteHost(this.Host, logMessage);
+ }
+
+ private void SendTheMessageToRemoteHost(string host, string message)
+ {
+ // TODO - write me
+ }
+ }
+}
diff --git a/examples/web/NLogC.cpp b/examples/web/NLogC.cpp
new file mode 100644
index 0000000..5fdaf14
--- /dev/null
+++ b/examples/web/NLogC.cpp
@@ -0,0 +1,26 @@
+
+//
+// ANSI functions
+//
+int NLog_ConfigureFromFileA(const char *fileName);
+void NLog_LogA(NLogLevel level, const char *loggerName, const char *logMessage, ...);
+void NLog_TraceA(const char *loggerName, const char *logMessage, ...);
+void NLog_DebugA(const char *loggerName, const char *logMessage, ...);
+void NLog_InfoA(const char *loggerName, const char *logMessage, ...);
+void NLog_WarnA(const char *loggerName, const char *logMessage, ...);
+void NLog_ErrorA(const char *loggerName, const char *logMessage, ...);
+void NLog_FatalA(const char *loggerName, const char *logMessage, ...);
+void NLog_LogVA(NLogLevel level, const char *loggerName, const char *logMessage, va_list args);
+
+//
+// Unicode functions
+//
+int NLog_ConfigureFromFileW(const wchar_t *fileName);
+void NLog_LogW(NLogLevel level, const wchar_t *loggerName, const wchar_t *logMessage, ...);
+void NLog_TraceW(const wchar_t *loggerName, const wchar_t *logMessage, ...);
+void NLog_DebugW(const wchar_t *loggerName, const wchar_t *logMessage, ...);
+void NLog_InfoW(const wchar_t *loggerName, const wchar_t *logMessage, ...);
+void NLog_WarnW(const wchar_t *loggerName, const wchar_t *logMessage, ...);
+void NLog_ErrorW(const wchar_t *loggerName, const wchar_t *logMessage, ...);
+void NLog_FatalW(const wchar_t *loggerName, const wchar_t *logMessage, ...);
+void NLog_LogVW(NLogLevel level, const wchar_t *loggerName, const wchar_t *logMessage, va_list args);
diff --git a/examples/web/NLogCdef.cpp b/examples/web/NLogCdef.cpp
new file mode 100644
index 0000000..a3e5876
--- /dev/null
+++ b/examples/web/NLogCdef.cpp
@@ -0,0 +1,28 @@
+//
+// TCHAR macros
+//
+#ifdef UNICODE
+
+#define NLog_Log NLog_LogW
+#define NLog_LogV NLog_LogVW
+#define NLog_Trace NLog_TraceW
+#define NLog_Debug NLog_DebugW
+#define NLog_Info NLog_InfoW
+#define NLog_Warn NLog_WarnW
+#define NLog_Error NLog_ErrorW
+#define NLog_Fatal NLog_FatalW
+#define NLog_ConfigureFromFile NLog_ConfigureFromFileW
+
+#else
+
+#define NLog_Log NLog_LogA
+#define NLog_LogV NLog_LogVA
+#define NLog_Trace NLog_TraceA
+#define NLog_Debug NLog_DebugA
+#define NLog_Info NLog_InfoA
+#define NLog_Warn NLog_WarnA
+#define NLog_Error NLog_ErrorA
+#define NLog_Fatal NLog_FatalA
+#define NLog_ConfigureFromFile NLog_ConfigureFromFileA
+
+#endif
diff --git a/examples/web/Performance.cs b/examples/web/Performance.cs
new file mode 100644
index 0000000..42d4060
--- /dev/null
+++ b/examples/web/Performance.cs
@@ -0,0 +1,16 @@
+using NLog;
+
+class MyClass {
+ // storing logger reference in a static variable is clean and fast
+ static Logger logger = LogManager.GetLogger("MyClass");
+
+ static void Main()
+ {
+ logger.Debug("This is a debugging message");
+
+ // it is not recommended to get the logger and store it in a local variable
+ Logger logger2 = LogManager.GetLogger("MyClass");
+ logger2.Debug("This is a debugging message");
+ }
+}
+
diff --git a/examples/web/app.config b/examples/web/app.config
new file mode 100644
index 0000000..4ecdd0a
--- /dev/null
+++ b/examples/web/app.config
@@ -0,0 +1,10 @@
+<configuration>
+ <configSections>
+ <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
+ <!-- other configSections go here -->
+ </configSections>
+ <nlog>
+ <!-- configuration parameters go here -->
+ </nlog>
+</configuration>
+
diff --git a/examples/web/article1.cs b/examples/web/article1.cs
new file mode 100644
index 0000000..8916401
--- /dev/null
+++ b/examples/web/article1.cs
@@ -0,0 +1,21 @@
+using NLog;
+
+namespace Firma.Komponent
+{
+ public class Klasa {
+ private static Logger logger = LogManager.GetLogger("Firma.Komponent.Klasa");
+ // private static Logger logger = LogManager.GetCurrentClassLogger();
+
+ static void Main()
+ {
+ logger.Info("Informacja");
+ logger.Warn("Ostrze¿enie {0}", "testowe");
+ logger.Error("B³¹d");
+ logger.Fatal("B³¹d krytyczny");
+ // formatowanie w stylu Console.WriteLine()
+ logger.Debug("Wynik {0} {1}", 1 + 2, "zzz");
+ // formatowanie z u¿yciem IFormatProvider
+ logger.Debug(CultureInfo.InvariantCulture, "Bie¿¹ca data {0}", DateTime.Now);
+ }
+ }
+}
diff --git a/examples/web/article2.cs b/examples/web/article2.cs
new file mode 100644
index 0000000..42de6d2
--- /dev/null
+++ b/examples/web/article2.cs
@@ -0,0 +1,33 @@
+using NLog;
+
+namespace Firma.Komponent
+{
+ public class Klasa {
+ private static Logger logger = LogManager.GetLogger("Firma.Komponent.Klasa");
+ // private static Logger logger = LogManager.GetCurrentClassLogger();
+
+ static void Main()
+ {
+ logger.Info("Informacja");
+ logger.Warn("Ostrze¿enie {0}", "testowe");
+ logger.Error("B³¹d");
+ logger.Fatal("B³¹d krytyczny");
+
+ // w przypadku du¿ej liczby parametrów warto sprawdziæ
+ // czy komunikat ma szansê byæ gdziekolwiek zapisany
+ if (logger.IsDebugEnabled) {
+ int x = 3;
+ int y = 5;
+
+ logger.Debug("x={0}, y={1}", x, y);
+ }
+
+ // formatowanie w stylu Console.WriteLine()
+ logger.Debug("Wynik {0} {1}", 1 + 2, "zzz");
+
+ // formatowanie z u¿yciem IFormatProvider
+ logger.Debug(CultureInfo.InvariantCulture,
+ "Bie¿¹ca data {0}", DateTime.Now);
+ }
+ }
+}
diff --git a/examples/web/article3.nlog b/examples/web/article3.nlog
new file mode 100644
index 0000000..3a27cb6
--- /dev/null
+++ b/examples/web/article3.nlog
@@ -0,0 +1,9 @@
+<nlog>
+ <targets>
+ <target name="konsola" type="Console" layout="${longdate} ${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="konsola" />
+ </rules>
+</nlog>
diff --git a/examples/web/article4.nlog b/examples/web/article4.nlog
new file mode 100644
index 0000000..5d38c54
--- /dev/null
+++ b/examples/web/article4.nlog
@@ -0,0 +1,9 @@
+<nlog>
+ <targets>
+ <target name="codziennyPlik" type="File" layout="${longdate} ${message}" filename="${shortdate}.log" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="codziennyPlik" />
+ </rules>
+</nlog>
diff --git a/examples/web/article5.nlog b/examples/web/article5.nlog
new file mode 100644
index 0000000..8b7bfdd
--- /dev/null
+++ b/examples/web/article5.nlog
@@ -0,0 +1,24 @@
+<nlog>
+ <targets>
+ <target name="codziennyPlik" type="File" layout="${longdate} ${message}" filename="${shortdate}.log" />
+ <target name="konsola" type="Console" />
+ <target name="bledy" type="File" filename="errors.log" />
+ <target name="bazaDanych" type="Database">
+ <dbprovider>mssql</dbprovider>
+ <dbhost>.</dbhost>
+ <dbdatabase>NLogDatabase</dbdatabase>
+ <dbusername>nloguser</dbusername>
+ <dbpassword>nlogpassword</dbpassword>
+
+ <commandText>
+ insert into LogTable(time_stamp,level,logger,message)
+ values(@time_stamp, @level, @logger, @message);
+ </commandText>
+
+ <parameter name="@time_stamp" layout="${date}" />
+ <parameter name="@level" layout="${level}" />
+ <parameter name="@logger" layout="${logger}" />
+ <parameter name="@message" layout="${message}" />
+ </target>
+ </targets>
+</nlog>
diff --git a/examples/web/article6.nlog b/examples/web/article6.nlog
new file mode 100644
index 0000000..f1283c7
--- /dev/null
+++ b/examples/web/article6.nlog
@@ -0,0 +1,7 @@
+<rules>
+ <logger name="FooBar*" minlevel="Trace" writeTo="" final="true" />
+ <logger name="*" levels="Warn,Error" writeTo="bledy,bazaDanych" />
+ <logger name="Gizmo*" minlevel="Info" writeTo="bazaDanych" />
+ <logger name="*" minlevel="Info" writeTo="codziennyPlik" />
+ <logger name="*" minlevel="Trace" writeTo="konsola" />
+</rules>
diff --git a/examples/web/benchmark_log4net.cs b/examples/web/benchmark_log4net.cs
new file mode 100644
index 0000000..d4f3e39
--- /dev/null
+++ b/examples/web/benchmark_log4net.cs
@@ -0,0 +1,30 @@
+#if LOG4NET
+ ILog logger = LogManager.GetLogger("somelogger");
+#else
+ Logger logger = LogManager.GetLogger("somelogger");
+#endif
+
+// Case 1. No formatting:
+logger.Debug("This is a message without formatting.");
+
+// Case 2. One format parameter
+#if LOG4NET
+ logger.Debug(String.Format("This is a message with {0} format parameter", 1));
+#else
+ logger.Debug("This is a message with {0} format parameter", 1);
+#endif
+
+// Case 3. Two format parameters
+#if LOG4NET
+ logger.Debug(String.Format("This is a message with {0}{1} parameters", 2, "o"));
+#else
+ logger.Debug("This is a message with {0}{1} parameters", 2, "o");
+#endif
+
+// Case 4. Three format parameters
+#if LOG4NET
+ logger.Debug(String.Format("This is a message with {0}{1}{2} parameters", "thr", 3, 3));
+#else
+ logger.Debug("This is a message with {0}{1}{2} parameters", "thr", 3, 3);
+#endif
+
diff --git a/examples/web/benchmark_nlog.cs b/examples/web/benchmark_nlog.cs
new file mode 100644
index 0000000..5127449
--- /dev/null
+++ b/examples/web/benchmark_nlog.cs
@@ -0,0 +1,29 @@
+Logger logger = LogManager.GetLogger("somelogger");
+
+// Case 1. No formatting
+logger.Debug("This is a message without formatting.");
+
+// Case 2. One format parameter
+logger.Debug("This is a message with {0} format parameter", 1);
+
+// Case 3. Two format parameters
+logger.Debug("This is a message with {0}{1} parameters", 2, "o");
+
+// Case 4. Three format parameters
+logger.Debug("This is a message with {0}{1}{2} parameters", "thr", 3, 3);
+
+// Case 1a. No formatting, using a guard.
+if (logger.IsDebugEnabled)
+ logger.Debug("This is a message without formatting.");
+
+// Case 2a. One format parameter, using a guard.
+if (logger.IsDebugEnabled)
+ logger.Debug("This is a message with {0} format parameter", 1);
+
+// Case 3a. Two format parameters, using a guard.
+if (logger.IsDebugEnabled)
+ logger.Debug("This is a message with {0}{1} parameters", 2, "o");
+
+// Case 4a. Three format parameters, using a guard.
+if (logger.IsDebugEnabled)
+ logger.Debug("This is a message with {0}{1}{2} parameters", "thr", 3, 3);
diff --git a/examples/web/config1.nlog b/examples/web/config1.nlog
new file mode 100644
index 0000000..39b18e0
--- /dev/null
+++ b/examples/web/config1.nlog
@@ -0,0 +1,4 @@
+<nlog>
+ <!-- configuration parameters go here -->
+</nlog>
+
diff --git a/examples/web/config10.nlog b/examples/web/config10.nlog
new file mode 100644
index 0000000..43a346e
--- /dev/null
+++ b/examples/web/config10.nlog
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<nlog>
+ <extensions>
+ <add assembly="MyAssembly" />
+ </extensions>
+
+ <targets>
+ <target name="console" type="Console" />
+ </targets>
+
+ <rules>
+ <logger name="*" minLevel="Info" appendTo="console">
+ <filters>
+ <hourRange fromHour="10" toHour="12" action="Ignore" />
+ </filters>
+ </logger>
+ </rules>
+</nlog>
diff --git a/examples/web/config11.nlog b/examples/web/config11.nlog
new file mode 100644
index 0000000..40406dd
--- /dev/null
+++ b/examples/web/config11.nlog
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<nlog>
+ <targets>
+ <target name="file" type="File" filename="${basedir}/logs/logfile.txt"
+ layout="${longdate} ${level:uppercase=true} ${logger} ${aspnet-session:variable=UserName} ${threadid} ${callsite} ${message}" />
+ <target name="trace" type="ASPNetTrace"
+ layout="${level:uppercase=true} ${callsite} ${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minLevel="Info" appendTo="trace" />
+ <logger name="*" minLevel="Debug" appendTo="file" />
+ </rules>
+</nlog>
diff --git a/examples/web/config12.nlog b/examples/web/config12.nlog
new file mode 100644
index 0000000..bc52c0e
--- /dev/null
+++ b/examples/web/config12.nlog
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<nlog autoReload="true">
+ <!-- config goes here -->
+</nlog>
diff --git a/examples/web/config2.nlog b/examples/web/config2.nlog
new file mode 100644
index 0000000..9b93013
--- /dev/null
+++ b/examples/web/config2.nlog
@@ -0,0 +1,3 @@
+<nlog>
+ <include file="${machinename}.config.log" />
+</nlog>
diff --git a/examples/web/config3.nlog b/examples/web/config3.nlog
new file mode 100644
index 0000000..a1fe382
--- /dev/null
+++ b/examples/web/config3.nlog
@@ -0,0 +1,24 @@
+<?xml version="1.0" ?>
+<nlog>
+ <targets>
+ <target name="console" type="Console" />
+ <target name="file1" type="File" filename="file1.log" />
+ <target name="file2" type="File" filename="file2.log" />
+ <target name="file3" type="File" filename="file3.log" />
+ </targets>
+
+ <rules>
+ <!-- SQL messages to file3.log but nowhere else-->
+ <logger name="*SQL*" appendTo="file3" final="true" />
+
+ <!-- Info and Error messages go to the console and file1.log -->
+ <logger levels="Info,Error" appendTo="console,file1" />
+
+ <!-- log all Debug messages to file1.log -->
+ <logger name="*" level="Debug" appendTo="file1" />
+
+ <!-- log error and fatal messages to file2.log -->
+ <logger name="*" minlevel="Error" appendTo="file2" />
+ </rules>
+</nlog>
+
diff --git a/examples/web/config4.nlog b/examples/web/config4.nlog
new file mode 100644
index 0000000..ae27713
--- /dev/null
+++ b/examples/web/config4.nlog
@@ -0,0 +1,25 @@
+<?xml version="1.0" ?>
+<nlog>
+ <extensions>
+ <!--
+ Load assembly from the specified file the path is
+ relative to the config file directory
+ so you need to use bin/filename.dll for web applications
+ -->
+
+ <add assemblyFile="NLog.Extensions.dll" />
+
+ <!-- load assembly using the specified name -->
+ <add assembly="NLog.Extensions" />
+
+ <!--
+ Load assembly from the specified file and prefix
+ all targets and layout renderers with 'zzz'
+
+ This can be used to avoid name clashes on extension dlls.
+ -->
+
+ <add prefix="zzz" assemblyFile="NLog.Extensions.dll" />
+ </extensions>
+</nlog>
+
diff --git a/examples/web/config5.nlog b/examples/web/config5.nlog
new file mode 100644
index 0000000..5dd81a5
--- /dev/null
+++ b/examples/web/config5.nlog
@@ -0,0 +1,10 @@
+<?xml version="1.0" ?>
+<nlog>
+ <targets>
+ <target name="name1" type="type1" layout="layout1" parameter1="..." parameterN="..." />
+ <target name="name2" type="type2" layout="layout2" parameter1="..." parameterN="..." />
+ <target name="name3" type="type3" layout="layout3" parameter1="..." parameterN="..." />
+ <target name="name4" type="type4" layout="layout4" parameter1="..." parameterN="..." />
+ </targets>
+</nlog>
+
diff --git a/examples/web/config6.nlog b/examples/web/config6.nlog
new file mode 100644
index 0000000..0c9bbfa
--- /dev/null
+++ b/examples/web/config6.nlog
@@ -0,0 +1,23 @@
+<?xml version="1.0" ?>
+<configuration>
+ <configSections>
+ <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
+ </configSections>
+
+ <nlog>
+ <targets>
+ <target name="console" type="Console" />
+ <target name="file1" type="File" filename="file1.log" />
+ <target name="file2" type="File" filename="file2.log" />
+ <target name="file3" type="File" filename="file3.log" />
+ </targets>
+
+ <rules>
+ <logger name="*" levels="Info,Warn,Error" writeTo="console" />
+ <logger name="*" level="Debug" writeTo="file1" />
+ <logger name="*" minlevel="Error" writeTo="file2" />
+ <logger name="*SQL*" writeTo="file3" />
+ </rules>
+ </nlog>
+</configuration>
+
diff --git a/examples/web/config7.nlog b/examples/web/config7.nlog
new file mode 100644
index 0000000..2597b61
--- /dev/null
+++ b/examples/web/config7.nlog
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<nlog>
+ <extensions>
+ <add assembly="MyAssembly" />
+ </extensions>
+
+ <targets>
+ <target name="a1" type="MyFirst" host="localhost" />
+ </targets>
+
+ <rules>
+ <logger name="*" minLevel="Info" appendTo="a1" />
+ </rules>
+</nlog>
diff --git a/examples/web/config8.nlog b/examples/web/config8.nlog
new file mode 100644
index 0000000..d1797f5
--- /dev/null
+++ b/examples/web/config8.nlog
@@ -0,0 +1,9 @@
+<nlog>
+ <targets>
+ <target name="console" type="Console" />
+ </targets>
+
+ <rules>
+ <logger name="*" appendTo="console" />
+ </rules>
+</nlog>
diff --git a/examples/web/config8a.nlog b/examples/web/config8a.nlog
new file mode 100644
index 0000000..2fb89c4
--- /dev/null
+++ b/examples/web/config8a.nlog
@@ -0,0 +1,9 @@
+<nlog>
+ <targets>
+ <target name="console" type="Console" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Warn" appendTo="console" />
+ </rules>
+</nlog>
diff --git a/examples/web/config9.nlog b/examples/web/config9.nlog
new file mode 100644
index 0000000..a5cc221
--- /dev/null
+++ b/examples/web/config9.nlog
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<nlog>
+ <extensions>
+ <add assembly="MyAssembly" />
+ </extensions>
+
+ <targets>
+ <target name="console" type="Console" layout="${hour:showminutes=false} ${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minLevel="Info" appendTo="console" />
+ </rules>
+</nlog>
diff --git a/examples/web/test.js b/examples/web/test.js
new file mode 100644
index 0000000..9955d4d
--- /dev/null
+++ b/examples/web/test.js
@@ -0,0 +1,44 @@
+var logmanager = new ActiveXObject("NLog.LogManager");
+WScript.Echo("Loading config from file 'config8.nlog'...");
+logmanager.InternalLogToConsole = true;
+logmanager.InternalLogFile = "internal_log.txt";
+logmanager.InternalLogLevel = "Info";
+logmanager.LoadConfigFromFile("config8.nlog");
+
+var logger = new ActiveXObject("NLog.Logger");
+logger.LoggerName = "TestLogger";
+logger.Log("Trace", "This is a trace message");
+logger.Log("Debug", "This is a debugging message");
+logger.Log("Info", "This is an information message");
+logger.Log("Warn", "This is a warning message");
+logger.Log("Error", "This is an error");
+logger.Log("Fatal", "This is a fatal message");
+
+logger.Trace("This is a trace message");
+logger.Debug("This is a debugging message");
+logger.Info("This is an information message");
+logger.Warn("This is a warning message");
+logger.Error("This is an error");
+logger.Fatal("This is a fatal message");
+
+WScript.Echo("Loading config from file 'config8a.nlog'...");
+logmanager.InternalLogToConsole = false;
+logmanager.InternalLogFile = "internal_log.txt";
+logmanager.InternalLogLevel = "Fatal";
+logmanager.LoadConfigFromFile("config8a.nlog");
+
+logger.Log("Trace", "This is a trace message");
+logger.Log("Debug", "This is a debugging message");
+logger.Log("Info", "This is an information message");
+logger.Log("Warn", "This is a warning message");
+logger.Log("Error", "This is an error");
+logger.Log("Fatal", "This is a fatal message");
+
+logger.Trace("This is a trace message");
+logger.Debug("This is a debugging message");
+logger.Info("This is an information message");
+logger.Warn("This is a warning message");
+logger.Error("This is an error");
+logger.Fatal("This is a fatal message");
+
+
diff --git a/examples/web/test.vbs b/examples/web/test.vbs
new file mode 100644
index 0000000..004dece
--- /dev/null
+++ b/examples/web/test.vbs
@@ -0,0 +1,46 @@
+Dim logmanager, logger
+
+Set logmanager = CreateObject("NLog.LogManager")
+WScript.Echo "Loading config from file 'config8.nlog' with internal logging to console..."
+logmanager.InternalLogToConsole = true
+logmanager.InternalLogFile = "internal_log.txt"
+logmanager.InternalLogLevel = "Info"
+logmanager.LoadConfigFromFile "config8.nlog"
+
+Set logger = CreateObject("NLog.Logger")
+logger.LoggerName = "TestLogger"
+logger.Log "Trace", "This is a trace message"
+logger.Log "Debug", "This is a debugging message"
+logger.Log "Info", "This is an information message"
+logger.Log "Warn", "This is a warning message"
+logger.Log "Error", "This is an error"
+logger.Log "Fatal", "This is a fatal message"
+
+logger.Trace "This is a trace message"
+logger.Debug "This is a debugging message"
+logger.Info "This is an information message"
+logger.Warn "This is a warning message"
+logger.Error "This is an error"
+logger.Fatal "This is a fatal message"
+
+WScript.Echo "Loading config from file 'config8a.nlog' without internal logging..."
+logmanager.InternalLogToConsole = false
+logmanager.InternalLogFile = "internal_log.txt"
+logmanager.InternalLogLevel = "Fatal"
+logmanager.LoadConfigFromFile "config8a.nlog"
+
+logger.Log "Trace", "This is a trace message"
+logger.Log "Debug", "This is a debugging message"
+logger.Log "Info", "This is an information message"
+logger.Log "Warn", "This is a warning message"
+logger.Log "Error", "This is an error"
+logger.Log "Fatal", "This is a fatal message"
+
+logger.Trace "This is a trace message"
+logger.Debug "This is a debugging message"
+logger.Info "This is an information message"
+logger.Warn "This is a warning message"
+logger.Error "This is an error"
+logger.Fatal "This is a fatal message"
+
+
diff --git a/examples/web/tutorial.cs b/examples/web/tutorial.cs
new file mode 100644
index 0000000..5a56057
--- /dev/null
+++ b/examples/web/tutorial.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Globalization;
+
+using NLog;
+
+class MyClass {
+ static Logger logger = LogManager.GetLogger("MyClass");
+
+ static void Main()
+ {
+ // you can use an interface known from log4net
+ logger.Trace("This is a trace message");
+ logger.Debug("This is a debugging message");
+ logger.Info("This is a information message");
+ logger.Warn("This is a warning message");
+ logger.Error("This is an error");
+ logger.Fatal("This is a fatal error message");
+
+ // you can ask if the logging is enabled before writing
+ if (logger.IsDebugEnabled) {
+ logger.Debug("Some debug info");
+ }
+
+ // you can use WriteLine() style formatting
+ logger.Debug("The result is {0} {1}", 1 + 2, "zzz");
+
+ // you can even pass IFormatProvider for maximum flexibility
+ logger.Debug(CultureInfo.InvariantCulture,
+ "The current time is {0}", DateTime.Now);
+
+ // you can ask if the logging is enabled for specified level
+ if (logger.IsEnabled(LogLevel.Warn)) {
+ // and you can write the message for a particular level, too
+ logger.Log(LogLevel.Warn, "Some warning info");
+ }
+ }
+}
diff --git a/src/NLog.ComInterop/AssemblyBuildInfo.cs b/src/NLog.ComInterop/AssemblyBuildInfo.cs
new file mode 100644
index 0000000..a63b185
--- /dev/null
+++ b/src/NLog.ComInterop/AssemblyBuildInfo.cs
@@ -0,0 +1,4 @@
+// do not modify this file. It will be automatically regenerated
+// based on the version number saved in src/NLog.ComInterop/AssemblyBuildInfo.cs is changed.
+using System.Reflection;
+[assembly: AssemblyVersion("1.0.0.505")]
diff --git a/src/NLog.ComInterop/AssemblyInfo.cs b/src/NLog.ComInterop/AssemblyInfo.cs
new file mode 100644
index 0000000..13e250b
--- /dev/null
+++ b/src/NLog.ComInterop/AssemblyInfo.cs
@@ -0,0 +1,60 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+
+#if DOTNET_1_0
+[assembly: AssemblyTitle("NLog COM Interop for .NET 1.0")]
+#elif DOTNET_1_1
+[assembly: AssemblyTitle("NLog COM Interop for .NET 1.1")]
+#elif DOTNET_2_0
+[assembly: AssemblyTitle("NLog COM Interop for .NET 2.0")]
+#else
+#error Cannot set AssemblyTitle
+#endif
+
+[assembly: AssemblyDescription("NLog COM Interop")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("NLog - http://www.nlog-project.org/")]
+[assembly: AssemblyProduct("NLog - .NET Logging Library")]
+[assembly: AssemblyCopyright("Copyright (c) 2004-2006 by Jaroslaw Kowalski")]
+[assembly: AssemblyCulture("")]
+
+[assembly: Guid("fb84adc2-a04b-4ff3-8a20-7c069c3cfa6f")]
+
+[assembly: CLSCompliant(true)]
+[assembly: ComVisible(true)]
diff --git a/src/NLog.ComInterop/AssemblySign.cs b/src/NLog.ComInterop/AssemblySign.cs
new file mode 100644
index 0000000..88fdb7c
--- /dev/null
+++ b/src/NLog.ComInterop/AssemblySign.cs
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System.Reflection;
+
+#if NANT
+[assembly: AssemblyKeyFile("src/NLog.snk")]
+#else
+[assembly: AssemblyKeyFile("../../../NLog.snk")]
+#endif
diff --git a/src/NLog.ComInterop/ILogManager.cs b/src/NLog.ComInterop/ILogManager.cs
new file mode 100644
index 0000000..1f0090c
--- /dev/null
+++ b/src/NLog.ComInterop/ILogManager.cs
@@ -0,0 +1,74 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace NLog.ComInterop
+{
+ /// <summary>
+ /// NLog COM Interop LogManager interface
+ /// </summary>
+ [Guid("7ee3af3b-ba37-45b6-8f5d-cc23bb46c698")]
+ [InterfaceType(ComInterfaceType.InterfaceIsDual)]
+ public interface ILogManager
+ {
+ /// <summary>
+ /// Loads NLog configuration from the specified file.
+ /// </summary>
+ /// <param name="fileName">The name of the file to load NLog configuration from</param>
+ void LoadConfigFromFile(string fileName);
+
+ /// <summary>
+ /// Internal log to the console.
+ /// </summary>
+ bool InternalLogToConsole { get; set; }
+
+ /// <summary>
+ /// Internal log file.
+ /// </summary>
+ string InternalLogFile { get; set; }
+
+ /// <summary>
+ /// The name of the internal log level.
+ /// </summary>
+ string InternalLogLevel { get; set; }
+
+ /// <summary>
+ /// Creates the specified logger object and assigns a LoggerName to it.
+ /// </summary>
+ /// <param name="name">Logger name</param>
+ /// <returns>The new logger instance.</returns>
+ ILogger GetLogger(string name);
+ }
+}
diff --git a/src/NLog.ComInterop/ILogger.cs b/src/NLog.ComInterop/ILogger.cs
new file mode 100644
index 0000000..6abe229
--- /dev/null
+++ b/src/NLog.ComInterop/ILogger.cs
@@ -0,0 +1,147 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace NLog.ComInterop
+{
+ /// <summary>
+ /// NLog COM Interop logger interface
+ /// </summary>
+ [Guid("757fd55a-cc93-4b53-a7a0-18e85620704a")]
+ [InterfaceType(ComInterfaceType.InterfaceIsDual)]
+ public interface ILogger
+ {
+ /// <summary>
+ /// Writes the diagnostic message at the specified level.
+ /// </summary>
+ /// <param name="level">The log level.</param>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ void Log(string level, string message);
+
+ /// <summary>
+ /// Writes the diagnostic message at the Trace level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ void Trace(string message);
+
+ /// <summary>
+ /// Writes the diagnostic message at the Debug level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ void Debug(string message);
+
+ /// <summary>
+ /// Writes the diagnostic message at the Info level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ void Info(string message);
+
+ /// <summary>
+ /// Writes the diagnostic message at the Warn level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ void Warn(string message);
+
+ /// <summary>
+ /// Writes the diagnostic message at the Error level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ void Error(string message);
+
+ /// <summary>
+ /// Writes the diagnostic message at the Fatal level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ void Fatal(string message);
+
+ /// <summary>
+ /// Checks if the specified log level is enabled.
+ /// </summary>
+ /// <param name="level">The log level.</param>
+ /// <returns>A value indicating whether the specified log level is enabled.</returns>
+ bool IsEnabled(string level);
+
+ /// <summary>
+ /// Returns the boolean value indicating whether the Trace level is enabled.
+ /// </summary>
+ bool IsTraceEnabled
+ {
+ get;
+ }
+ /// <summary>
+ /// Returns the boolean value indicating whether the Debug level is enabled.
+ /// </summary>
+ bool IsDebugEnabled
+ {
+ get;
+ }
+ /// <summary>
+ /// Returns the boolean value indicating whether the Info level is enabled.
+ /// </summary>
+ bool IsInfoEnabled
+ {
+ get;
+ }
+ /// <summary>
+ /// Returns the boolean value indicating whether the Warn level is enabled.
+ /// </summary>
+ bool IsWarnEnabled
+ {
+ get;
+ }
+ /// <summary>
+ /// Returns the boolean value indicating whether the Error level is enabled.
+ /// </summary>
+ bool IsErrorEnabled
+ {
+ get;
+ }
+ /// <summary>
+ /// Returns the boolean value indicating whether the Fatal level is enabled.
+ /// </summary>
+ bool IsFatalEnabled
+ {
+ get;
+ }
+
+ /// <summary>
+ /// The logger name.
+ /// </summary>
+ string LoggerName
+ {
+ get; set;
+ }
+ }
+}
diff --git a/src/NLog.ComInterop/LogManager.cs b/src/NLog.ComInterop/LogManager.cs
new file mode 100644
index 0000000..5c43171
--- /dev/null
+++ b/src/NLog.ComInterop/LogManager.cs
@@ -0,0 +1,82 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+using NLog;
+using NLog.Internal;
+using NLog.Config;
+
+namespace NLog.ComInterop
+{
+ /// <summary>
+ /// NLog COM Interop LogManager implementation
+ /// </summary>
+ [ComVisible(true)]
+ [ProgId("NLog.LogManager")]
+ [Guid("9a7e8d84-72e4-478a-9a05-23c7ef0cfca8")]
+ [ClassInterface(ClassInterfaceType.None)]
+ public class LogManager: ILogManager
+ {
+ void ILogManager.LoadConfigFromFile(string fileName)
+ {
+ NLog.LogManager.Configuration = new XmlLoggingConfiguration(fileName);
+ }
+
+ bool ILogManager.InternalLogToConsole
+ {
+ get { return NLog.Internal.InternalLogger.LogToConsole; }
+ set { NLog.Internal.InternalLogger.LogToConsole = value; }
+ }
+
+ string ILogManager.InternalLogLevel
+ {
+ get { return NLog.Internal.InternalLogger.LogLevel.ToString(); }
+ set { NLog.Internal.InternalLogger.LogLevel = NLog.LogLevel.FromString(value); }
+ }
+
+ string ILogManager.InternalLogFile
+ {
+ get { return NLog.Internal.InternalLogger.LogFile; }
+ set { NLog.Internal.InternalLogger.LogFile = value; }
+ }
+
+ ILogger ILogManager.GetLogger(string name)
+ {
+ ILogger l = new Logger();
+ l.LoggerName = name;
+ return l;
+ }
+ }
+}
diff --git a/src/NLog.ComInterop/Logger.cs b/src/NLog.ComInterop/Logger.cs
new file mode 100644
index 0000000..39fabf4
--- /dev/null
+++ b/src/NLog.ComInterop/Logger.cs
@@ -0,0 +1,158 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+using NLog;
+using NLog.Internal;
+
+namespace NLog.ComInterop
+{
+ /// <summary>
+ /// NLog COM Interop logger implementation
+ /// </summary>
+ [ComVisible(true)]
+ [ProgId("NLog.Logger")]
+ [Guid("181f39a8-41a8-4e35-91b6-5f8d96f5e61c")]
+ [ClassInterface(ClassInterfaceType.None)]
+ public class Logger: ILogger
+ {
+ private static NLog.Logger _defaultLogger = NLog.LogManager.CreateNullLogger();
+
+ private NLog.Logger _logger = _defaultLogger;
+ private string _loggerName = String.Empty;
+
+ void ILogger.Log(string level, string message)
+ {
+ _logger.Log(StringToLevel(level), message);
+ }
+
+ void ILogger.Trace(string message)
+ {
+ _logger.Trace(message);
+ }
+
+ void ILogger.Debug(string message)
+ {
+ _logger.Debug(message);
+ }
+
+ void ILogger.Info(string message)
+ {
+ _logger.Info(message);
+ }
+
+ void ILogger.Warn(string message)
+ {
+ _logger.Warn(message);
+ }
+
+ void ILogger.Error(string message)
+ {
+ _logger.Error(message);
+ }
+
+ void ILogger.Fatal(string message)
+ {
+ _logger.Fatal(message);
+ }
+
+ bool ILogger.IsEnabled(string level)
+ {
+ return _logger.IsEnabled(StringToLevel(level));
+ }
+
+ bool ILogger.IsTraceEnabled
+ {
+ get { return _logger.IsTraceEnabled; }
+ }
+
+ bool ILogger.IsDebugEnabled
+ {
+ get { return _logger.IsDebugEnabled; }
+ }
+
+ bool ILogger.IsInfoEnabled
+ {
+ get { return _logger.IsInfoEnabled; }
+ }
+
+ bool ILogger.IsWarnEnabled
+ {
+ get { return _logger.IsWarnEnabled; }
+ }
+
+ bool ILogger.IsErrorEnabled
+ {
+ get { return _logger.IsErrorEnabled; }
+ }
+
+ bool ILogger.IsFatalEnabled
+ {
+ get { return _logger.IsFatalEnabled; }
+ }
+
+ string ILogger.LoggerName
+ {
+ get { return _loggerName; }
+ set
+ {
+ _loggerName = value;
+ _logger = NLog.LogManager.GetLogger(value);
+ }
+ }
+
+ private static LogLevel StringToLevel(string s)
+ {
+ switch (s[0])
+ {
+ case 'T':
+ return LogLevel.Trace;
+ case 'D':
+ return LogLevel.Debug;
+ case 'I':
+ return LogLevel.Info;
+ case 'W':
+ return LogLevel.Warn;
+ case 'E':
+ return LogLevel.Error;
+ case 'F':
+ return LogLevel.Fatal;
+
+ default:
+ throw new NotSupportedException("LogLevel not supported: " + s);
+ }
+ }
+ }
+}
diff --git a/src/NLog.ComInterop/NLog.ComInterop.vs2003.csproj b/src/NLog.ComInterop/NLog.ComInterop.vs2003.csproj
new file mode 100644
index 0000000..407a77d
--- /dev/null
+++ b/src/NLog.ComInterop/NLog.ComInterop.vs2003.csproj
@@ -0,0 +1,125 @@
+<VisualStudioProject>
+ <CSHARP
+ ProjectType = "Local"
+ ProductVersion = "7.10.3077"
+ SchemaVersion = "2.0"
+ ProjectGuid = "{B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}"
+ >
+ <Build>
+ <Settings
+ ApplicationIcon = ""
+ AssemblyKeyContainerName = ""
+ AssemblyName = "NLog.ComInterop"
+ AssemblyOriginatorKeyFile = ""
+ DefaultClientScript = "JScript"
+ DefaultHTMLPageLayout = "Grid"
+ DefaultTargetSchema = "IE50"
+ DelaySign = "false"
+ OutputType = "Library"
+ PreBuildEvent = '"$(ProjectDir)..\..\tools\UpdateBuildNumber.exe" "$(ProjectDir)..\..\NLog.version" "$(ProjectDir)AssemblyBuildInfo.cs" "$(ProjectDir)..\..\build\NLog.buildversion"'
+ PostBuildEvent = ""
+ RootNamespace = "NLog.ComInterop"
+ RunPostBuildEvent = "OnBuildSuccess"
+ StartupObject = ""
+ >
+ <Config
+ Name = "Debug"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "DOTNET;DOTNET_1_1"
+ DocumentationFile = "NLog.ComInterop.xml"
+ DebugSymbols = "true"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = ""
+ Optimize = "false"
+ OutputPath = "bin\Debug\"
+ RegisterForComInterop = "true"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ <Config
+ Name = "Release"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "DOTNET;DOTNET_1_1"
+ DocumentationFile = "NLog.ComInterop.xml"
+ DebugSymbols = "false"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = ""
+ Optimize = "false"
+ OutputPath = "bin\Release\"
+ RegisterForComInterop = "true"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "1"
+ />
+ </Settings>
+ <References>
+ <Reference
+ Name = "System"
+ AssemblyName = "System"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll"
+ />
+ <Reference
+ Name = "System.XML"
+ AssemblyName = "System.Xml"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
+ />
+ <Reference
+ Name = "NLog.vs2003"
+ Project = "{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+ Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+ />
+ </References>
+ </Build>
+ <Files>
+ <Include>
+ <File
+ RelPath = "AssemblyBuildInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "AssemblyInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "AssemblySign.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "ILogger.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "ILogManager.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Logger.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LogManager.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ </Include>
+ </Files>
+ </CSHARP>
+</VisualStudioProject>
+
diff --git a/src/NLog.ComInterop/NLog.ComInterop.vs2005.csproj b/src/NLog.ComInterop/NLog.ComInterop.vs2005.csproj
new file mode 100644
index 0000000..bf2f026
--- /dev/null
+++ b/src/NLog.ComInterop/NLog.ComInterop.vs2005.csproj
@@ -0,0 +1,119 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectType>Local</ProjectType>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{B3F8E5FB-C9D4-4C12-841F-8009EB60DB3D}</ProjectGuid>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ApplicationIcon>
+ </ApplicationIcon>
+ <AssemblyKeyContainerName>
+ </AssemblyKeyContainerName>
+ <AssemblyName>NLog.ComInterop</AssemblyName>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <DefaultClientScript>JScript</DefaultClientScript>
+ <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+ <DefaultTargetSchema>IE50</DefaultTargetSchema>
+ <DelaySign>false</DelaySign>
+ <OutputType>Library</OutputType>
+ <RootNamespace>NLog.ComInterop</RootNamespace>
+ <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+ <StartupObject>
+ </StartupObject>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <OutputPath>bin\Debug\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>DOTNET;DOTNET_1_1</DefineConstants>
+ <DocumentationFile>NLog.ComInterop.xml</DocumentationFile>
+ <DebugSymbols>true</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>1699</NoWarn>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>true</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>4</WarningLevel>
+ <DebugType>full</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <OutputPath>bin\Release\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>DOTNET;DOTNET_1_1</DefineConstants>
+ <DocumentationFile>NLog.ComInterop.xml</DocumentationFile>
+ <DebugSymbols>false</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>1699</NoWarn>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>true</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>4</WarningLevel>
+ <DebugType>none</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System">
+ <Name>System</Name>
+ </Reference>
+ <Reference Include="System.Xml">
+ <Name>System.XML</Name>
+ </Reference>
+ <ProjectReference Include="..\NLog\NLog.vs2005.csproj">
+ <Name>NLog.vs2005</Name>
+ <Project>{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}</Project>
+ <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AssemblyInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="AssemblySign.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="ILogger.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="ILogManager.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Logger.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LogManager.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="AssemblyBuildInfo.cs" />
+ </ItemGroup>
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>"$(ProjectDir)..\..\tools\UpdateBuildNumber.exe" "$(ProjectDir)..\..\NLog.version" "$(ProjectDir)AssemblyBuildInfo.cs" "$(ProjectDir)..\..\build\NLog.buildversion"</PreBuildEvent>
+ <PostBuildEvent>
+ </PostBuildEvent>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/src/NLog.ComInterop/config.nlog b/src/NLog.ComInterop/config.nlog
new file mode 100644
index 0000000..d1797f5
--- /dev/null
+++ b/src/NLog.ComInterop/config.nlog
@@ -0,0 +1,9 @@
+<nlog>
+ <targets>
+ <target name="console" type="Console" />
+ </targets>
+
+ <rules>
+ <logger name="*" appendTo="console" />
+ </rules>
+</nlog>
diff --git a/src/NLog.ComInterop/test.js b/src/NLog.ComInterop/test.js
new file mode 100644
index 0000000..30abb73
--- /dev/null
+++ b/src/NLog.ComInterop/test.js
@@ -0,0 +1,6 @@
+var lm = new ActiveXObject("NLog.LogManager");
+lm.InternalLogToConsole = false;
+lm.LoadConfigFromFile("config.nlog");
+
+var l = new ActiveXObject("NLog.Logger");
+lm.GetLogger("A").Debug("b");
diff --git a/src/NLog.snk b/src/NLog.snk
new file mode 100644
index 0000000..ae6cb7d
Binary files /dev/null and b/src/NLog.snk differ
diff --git a/src/NLog/AssemblyBuildInfo.cs b/src/NLog/AssemblyBuildInfo.cs
new file mode 100644
index 0000000..fb45fac
--- /dev/null
+++ b/src/NLog/AssemblyBuildInfo.cs
@@ -0,0 +1,4 @@
+// do not modify this file. It will be automatically regenerated
+// based on the version number saved in 'NLog.version'
+using System.Reflection;
+[assembly: AssemblyVersion("1.0.0.505")]
diff --git a/src/NLog/AssemblyInfo.cs b/src/NLog/AssemblyInfo.cs
new file mode 100644
index 0000000..2b04028
--- /dev/null
+++ b/src/NLog/AssemblyInfo.cs
@@ -0,0 +1,72 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+
+#if DOTNET_1_0
+[assembly: AssemblyTitle("NLog for .NET 1.0")]
+#elif DOTNET_1_1
+[assembly: AssemblyTitle("NLog for .NET 1.1")]
+#elif DOTNET_2_0
+[assembly: AssemblyTitle("NLog for .NET 2.0")]
+#elif MONO_1_0
+[assembly: AssemblyTitle("NLog for Mono 1.0")]
+#elif MONO_2_0
+[assembly: AssemblyTitle("NLog for Mono 2.0")]
+#elif NETCF_1_0
+[assembly: AssemblyTitle("NLog for .NET Compact Framework 1.0")]
+#elif NETCF_2_0
+[assembly: AssemblyTitle("NLog for .NET Compact Framework 2.0")]
+#elif DOCUMENTATION
+[assembly: AssemblyTitle("NLog Documentation")]
+#endif
+
+[assembly: AssemblyDescription("NLog")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("NLog")]
+[assembly: AssemblyProduct("NLog - .NET Logging Library")]
+[assembly: AssemblyCopyright("Copyright (c) 2004-2006 by Jaroslaw Kowalski")]
+[assembly: AssemblyCulture("")]
+
+[assembly: CLSCompliant(true)]
+[assembly: ComVisible(false)]
+
+#if !NETCF
+//[assembly: ReflectionPermission(SecurityAction.RequestMinimum, MemberAccess = true, TypeInformation = true)]
+//[assembly: SecurityPermission(SecurityAction.RequestMinimum, Flags = SecurityPermissionFlag.Execution)]
+//[assembly: FileIOPermission(SecurityAction.RequestMinimum, Unrestricted = true)]
+#endif
diff --git a/src/NLog/AssemblySign.cs b/src/NLog/AssemblySign.cs
new file mode 100644
index 0000000..88fdb7c
--- /dev/null
+++ b/src/NLog/AssemblySign.cs
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System.Reflection;
+
+#if NANT
+[assembly: AssemblyKeyFile("src/NLog.snk")]
+#else
+[assembly: AssemblyKeyFile("../../../NLog.snk")]
+#endif
diff --git a/src/NLog/ConditionMethodAttribute.cs b/src/NLog/ConditionMethodAttribute.cs
new file mode 100644
index 0000000..6ae393e
--- /dev/null
+++ b/src/NLog/ConditionMethodAttribute.cs
@@ -0,0 +1,64 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog
+{
+ /// <summary>
+ /// Marks class as a log event Condition and assigns a name to it
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Method,AllowMultiple=true)]
+ public sealed class ConditionMethodAttribute: Attribute
+ {
+ private string _name;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ConditionMethodAttribute"/> and assigns
+ /// a name to it.
+ /// </summary>
+ /// <param name="name"></param>
+ public ConditionMethodAttribute(string name)
+ {
+ _name = name;
+ }
+
+ /// <summary>
+ /// The name of the condition method.
+ /// </summary>
+ public string Name
+ {
+ get { return _name; }
+ }
+ }
+}
diff --git a/src/NLog/ConditionMethodFactory.cs b/src/NLog/ConditionMethodFactory.cs
new file mode 100644
index 0000000..876905d
--- /dev/null
+++ b/src/NLog/ConditionMethodFactory.cs
@@ -0,0 +1,132 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Reflection;
+using System.Globalization;
+
+using NLog.Internal;
+using NLog.Config;
+
+namespace NLog
+{
+ /// <summary>
+ /// A factory of condition methods. Retrieves condition MethodInfos based on their names.
+ /// </summary>
+ public sealed class ConditionMethodFactory
+ {
+ private static MethodInfoDictionary _conditionMethods = new MethodInfoDictionary();
+
+ static ConditionMethodFactory()
+ {
+ foreach (Assembly a in ExtensionUtils.GetExtensionAssemblies())
+ {
+ AddConditionMethodsFromAssembly(a, "");
+ }
+ }
+
+ private ConditionMethodFactory(){}
+
+ /// <summary>
+ /// Removes all condition method information from the factory.
+ /// </summary>
+ public static void Clear()
+ {
+ _conditionMethods.Clear();
+ }
+
+ /// <summary>
+ /// Scans the specified assembly for types marked with <see cref="ConditionMethodsAttribute" /> and adds
+ /// them to the factory. Optionally it prepends the specified text to layout renderer names to avoid
+ /// naming collisions.
+ /// </summary>
+ /// <param name="theAssembly">The assembly to be scanned for layout renderers.</param>
+ /// <param name="prefix">The prefix to be prepended to layout renderer names.</param>
+ public static void AddConditionMethodsFromAssembly(Assembly theAssembly, string prefix)
+ {
+ try
+ {
+ InternalLogger.Debug("AddLogEventConditionsFromAssembly('{0}')", theAssembly.FullName);
+ foreach (Type t in theAssembly.GetTypes())
+ {
+ if (t.IsDefined(typeof(ConditionMethodsAttribute), false))
+ {
+ if (PlatformDetector.IsSupportedOnCurrentRuntime(t))
+ {
+ foreach (MethodInfo mi in t.GetMethods(BindingFlags.Public | BindingFlags.Static))
+ {
+ ConditionMethodAttribute[] malist = (ConditionMethodAttribute[])mi.GetCustomAttributes(typeof(ConditionMethodAttribute), false);
+
+ foreach (ConditionMethodAttribute ma in malist)
+ {
+ if (PlatformDetector.IsSupportedOnCurrentRuntime(mi))
+ {
+ AddConditionMethod(ma.Name, mi);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Failed to add LogEventConditions from '" + theAssembly.FullName + "': {0}", ex);
+ }
+
+ }
+
+ /// <summary>
+ /// Registers the specified condition method under a specified name.
+ /// </summary>
+ /// <param name="name">Name of the condition method.</param>
+ /// <param name="mi"><see cref="MethodInfo" /> of the method to be registered.</param>
+ public static void AddConditionMethod(string name, MethodInfo mi)
+ {
+ InternalLogger.Trace("AddConditionMethod('{0}','{1}')", name, mi);
+ _conditionMethods[name.ToLower(CultureInfo.InvariantCulture)] = mi;
+ }
+
+ /// <summary>
+ /// Returns the <see cref="MethodInfo"/> for the specified condition method.
+ /// </summary>
+ /// <param name="name">Name of the condition method.</param>
+ /// <returns><see cref="MethodInfo"/> object that represents the condition method.</returns>
+ public static MethodInfo CreateConditionMethod(string name)
+ {
+ return _conditionMethods[name.ToLower(CultureInfo.InvariantCulture)];
+ }
+ }
+}
diff --git a/src/NLog/ConditionMethodsAttribute.cs b/src/NLog/ConditionMethodsAttribute.cs
new file mode 100644
index 0000000..a69fb2e
--- /dev/null
+++ b/src/NLog/ConditionMethodsAttribute.cs
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog
+{
+ /// <summary>
+ /// Marks the class as containing condition methods.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class,AllowMultiple=true)]
+ public sealed class ConditionMethodsAttribute: Attribute
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="ConditionMethodsAttribute"/>.
+ /// </summary>
+ public ConditionMethodsAttribute()
+ {
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionAndExpression.cs b/src/NLog/Conditions/ConditionAndExpression.cs
new file mode 100644
index 0000000..55ca5a6
--- /dev/null
+++ b/src/NLog/Conditions/ConditionAndExpression.cs
@@ -0,0 +1,107 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Collections;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Condition <b>and</b> expression.
+ /// </summary>
+ internal sealed class ConditionAndExpression : ConditionExpression
+ {
+ /// <summary>
+ /// The left hand side of the AND expression.
+ /// </summary>
+ public readonly ConditionExpression Left;
+
+ /// <summary>
+ /// The right hand side of the AND expression.
+ /// </summary>
+ public readonly ConditionExpression Right;
+
+ private static object _boxedFalse = false;
+ private static object _boxedTrue = true;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ConditionAndExpression"/> and assigns
+ /// its Left and Right properties;
+ /// </summary>
+ /// <param name="left">Left hand side of the AND expression.</param>
+ /// <param name="right">Right hand side of the AND expression.</param>
+ public ConditionAndExpression(ConditionExpression left, ConditionExpression right)
+ {
+ this.Left = left;
+ this.Right = right;
+ }
+
+ /// <summary>
+ /// Evaluates the expression by evaluating <see cref="Left"/> and <see cref="Right"/> recursively.
+ /// </summary>
+ /// <param name="context">Evaluation context.</param>
+ /// <returns>The value of the conjunction operator.</returns>
+ public override object Evaluate(LogEventInfo context)
+ {
+ bool bval1 = (bool)Left.Evaluate(context);
+ if (!bval1)
+ return _boxedFalse;
+
+ bool bval2 = (bool)Right.Evaluate(context);
+ if (!bval2)
+ return _boxedFalse;
+
+ return _boxedTrue;
+ }
+
+ /// <summary>
+ /// Returns a string representation of this expression.
+ /// </summary>
+ /// <returns>(Left) or (Right) string</returns>
+ public override string ToString()
+ {
+ return "(" + Left + ") and (" + Right + ")";
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this expression to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ Left.PopulateLayouts(layouts);
+ Right.PopulateLayouts(layouts);
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionExpression.cs b/src/NLog/Conditions/ConditionExpression.cs
new file mode 100644
index 0000000..3ad45cb
--- /dev/null
+++ b/src/NLog/Conditions/ConditionExpression.cs
@@ -0,0 +1,61 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Base class for representing nodes in condition expression trees.
+ /// </summary>
+ public abstract class ConditionExpression
+ {
+ /// <summary>
+ /// Evaluates the expression.
+ /// </summary>
+ /// <param name="context">Evaluation context.</param>
+ /// <returns>Expression result.</returns>
+ public abstract object Evaluate(LogEventInfo context);
+
+ /// <summary>
+ /// Adds all layouts used by this expression to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public virtual void PopulateLayouts(LayoutCollection layouts)
+ {
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionExpressionCollection.cs b/src/NLog/Conditions/ConditionExpressionCollection.cs
new file mode 100644
index 0000000..9bec6a7
--- /dev/null
+++ b/src/NLog/Conditions/ConditionExpressionCollection.cs
@@ -0,0 +1,243 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace NLog.Conditions
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A collection of elements of type ConditionExpression
+ /// </summary>
+ internal class ConditionExpressionCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the ConditionExpressionCollection class.
+ /// </summary>
+ public ConditionExpressionCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the ConditionExpressionCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new ConditionExpressionCollection.
+ /// </param>
+ public ConditionExpressionCollection(ConditionExpression[]items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the ConditionExpressionCollection class, containing elements
+ /// copied from another instance of ConditionExpressionCollection
+ /// </summary>
+ /// <param name="items">
+ /// The ConditionExpressionCollection whose elements are to be added to the new ConditionExpressionCollection.
+ /// </param>
+ public ConditionExpressionCollection(ConditionExpressionCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this ConditionExpressionCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this ConditionExpressionCollection.
+ /// </param>
+ public virtual void AddRange(ConditionExpression[]items)
+ {
+ foreach (ConditionExpression item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another ConditionExpressionCollection to the end of this ConditionExpressionCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The ConditionExpressionCollection whose elements are to be added to the end of this ConditionExpressionCollection.
+ /// </param>
+ public virtual void AddRange(ConditionExpressionCollection items)
+ {
+ foreach (ConditionExpression item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type ConditionExpression to the end of this ConditionExpressionCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The ConditionExpression to be added to the end of this ConditionExpressionCollection.
+ /// </param>
+ public virtual void Add(ConditionExpression value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic ConditionExpression value is in this ConditionExpressionCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The ConditionExpression value to locate in this ConditionExpressionCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this ConditionExpressionCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(ConditionExpression value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this ConditionExpressionCollection
+ /// </summary>
+ /// <param name="value">
+ /// The ConditionExpression value to locate in the ConditionExpressionCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(ConditionExpression value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the ConditionExpressionCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the ConditionExpression is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The ConditionExpression to insert.
+ /// </param>
+ public virtual void Insert(int index, ConditionExpression value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the ConditionExpression at the given index in this ConditionExpressionCollection.
+ /// </summary>
+ public virtual ConditionExpression this[int index]
+ {
+ get { return (ConditionExpression)this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific ConditionExpression from this ConditionExpressionCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The ConditionExpression value to remove from this ConditionExpressionCollection.
+ /// </param>
+ public virtual void Remove(ConditionExpression value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by ConditionExpressionCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(ConditionExpressionCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public ConditionExpression Current
+ {
+ get { return (ConditionExpression)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (ConditionExpression)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this ConditionExpressionCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual ConditionExpressionCollection.Enumerator GetEnumerator()
+ {
+ return new ConditionExpressionCollection.Enumerator(this);
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionLayoutExpression.cs b/src/NLog/Conditions/ConditionLayoutExpression.cs
new file mode 100644
index 0000000..53ae58f
--- /dev/null
+++ b/src/NLog/Conditions/ConditionLayoutExpression.cs
@@ -0,0 +1,88 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+
+using System.Xml.Serialization;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Condition layout expression (represented by a string literal
+ /// with embedded ${})
+ /// </summary>
+ internal sealed class ConditionLayoutExpression : ConditionExpression
+ {
+ private Layout _layout;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ConditionLayoutExpression"/>
+ /// and initializes the layout.
+ /// </summary>
+ /// <param name="layout"></param>
+ public ConditionLayoutExpression(string layout)
+ {
+ _layout = new Layout(layout);
+ }
+
+ /// <summary>
+ /// Evaluates the expression by calculating the value
+ /// of the layout in the specified evaluation context.
+ /// </summary>
+ /// <param name="context">Evaluation context</param>
+ /// <returns>The value of the layout.</returns>
+ public override object Evaluate(LogEventInfo context)
+ {
+ return _layout.GetFormattedMessage(context);
+ }
+
+ /// <summary>
+ /// Returns a string representation of this expression.
+ /// </summary>
+ /// <returns>String literal in single quotes.</returns>
+ public override string ToString()
+ {
+ return "'" + _layout.Text + "'";
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this expression to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ _layout.PopulateLayouts(layouts);
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionLevelExpression.cs b/src/NLog/Conditions/ConditionLevelExpression.cs
new file mode 100644
index 0000000..be2f41b
--- /dev/null
+++ b/src/NLog/Conditions/ConditionLevelExpression.cs
@@ -0,0 +1,70 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+
+using System.Xml.Serialization;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Condition level expression (represented by the <b>level</b> keyword).
+ /// </summary>
+ internal sealed class ConditionLevelExpression : ConditionExpression
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="ConditionLevelExpression"/>.
+ /// </summary>
+ public ConditionLevelExpression() {}
+
+ /// <summary>
+ /// Evaluates to the current log level.
+ /// </summary>
+ /// <param name="context">Evaluation context. Ignored.</param>
+ /// <returns>The <see cref="LogLevel"/> object representing current log level.</returns>
+ public override object Evaluate(LogEventInfo context)
+ {
+ return context.Level;
+ }
+
+ /// <summary>
+ /// Returns a string representation of the expression.
+ /// </summary>
+ /// <returns><b>level</b> string.</returns>
+ public override string ToString()
+ {
+ return "level";
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionLiteralExpression.cs b/src/NLog/Conditions/ConditionLiteralExpression.cs
new file mode 100644
index 0000000..1bac997
--- /dev/null
+++ b/src/NLog/Conditions/ConditionLiteralExpression.cs
@@ -0,0 +1,77 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+
+using System.Xml.Serialization;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Condition literal expression (numeric, <b>LogLevel.XXX</b>, <b>true</b> or <b>false</b>)
+ /// </summary>
+ internal sealed class ConditionLiteralExpression : ConditionExpression
+ {
+ private object _literal;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ConditionLiteralExpression"/>
+ /// and initializes it with the specified value.
+ /// </summary>
+ /// <param name="literal"></param>
+ public ConditionLiteralExpression(object literal)
+ {
+ _literal = literal;
+ }
+
+ /// <summary>
+ /// Evaluates the expression.
+ /// </summary>
+ /// <param name="context">Evaluation context.</param>
+ /// <returns>The literal value as passed in the constructor.</returns>
+ public override object Evaluate(LogEventInfo context)
+ {
+ return _literal;
+ }
+
+ /// <summary>
+ /// Returns a string representation of the expression.
+ /// </summary>
+ /// <returns>The literal value.</returns>
+ public override string ToString()
+ {
+ return _literal.ToString();
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionLoggerNameExpression.cs b/src/NLog/Conditions/ConditionLoggerNameExpression.cs
new file mode 100644
index 0000000..eda24b6
--- /dev/null
+++ b/src/NLog/Conditions/ConditionLoggerNameExpression.cs
@@ -0,0 +1,70 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+
+using System.Xml.Serialization;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Condition logger name expression (represented by the <b>logger</b> keyword).
+ /// </summary>
+ internal sealed class ConditionLoggerNameExpression : ConditionExpression
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="ConditionLoggerNameExpression"/>.
+ /// </summary>
+ public ConditionLoggerNameExpression() {}
+
+ /// <summary>
+ /// Evaluates to the logger name.
+ /// </summary>
+ /// <param name="context">evaluation context</param>
+ /// <returns>The logger name</returns>
+ public override object Evaluate(LogEventInfo context)
+ {
+ return context.LoggerName;
+ }
+
+ /// <summary>
+ /// Returns a string representation of this expression
+ /// </summary>
+ /// <returns>a <b>logger</b> string</returns>
+ public override string ToString()
+ {
+ return "logger";
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionMessageExpression.cs b/src/NLog/Conditions/ConditionMessageExpression.cs
new file mode 100644
index 0000000..c87e054
--- /dev/null
+++ b/src/NLog/Conditions/ConditionMessageExpression.cs
@@ -0,0 +1,70 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+
+using System.Xml.Serialization;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Condition message expression (represented by the <b>message</b> keyword).
+ /// </summary>
+ internal sealed class ConditionMessageExpression : ConditionExpression
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="ConditionMessageExpression"/>.
+ /// </summary>
+ public ConditionMessageExpression() {}
+
+ /// <summary>
+ /// Evaluates to the logger message.
+ /// </summary>
+ /// <param name="context">evaluation context</param>
+ /// <returns>The logger message</returns>
+ public override object Evaluate(LogEventInfo context)
+ {
+ return context.FormattedMessage;
+ }
+
+ /// <summary>
+ /// Returns a string representation of this expression
+ /// </summary>
+ /// <returns>a <b>message</b> string</returns>
+ public override string ToString()
+ {
+ return "message";
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionMethodExpression.cs b/src/NLog/Conditions/ConditionMethodExpression.cs
new file mode 100644
index 0000000..f5e9cd9
--- /dev/null
+++ b/src/NLog/Conditions/ConditionMethodExpression.cs
@@ -0,0 +1,138 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Reflection;
+
+using System.Xml.Serialization;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Condition method invocation expression (represented by <b>method(p1,p2,p3)</b> syntax).
+ /// </summary>
+ internal sealed class ConditionMethodExpression : ConditionExpression
+ {
+ private string _name;
+ private ConditionExpressionCollection _parameters;
+ private MethodInfo _methodInfo;
+ private bool _acceptsLogEvent;
+
+ public ConditionMethodExpression() {}
+ public ConditionMethodExpression(string name, ConditionExpressionCollection parameters)
+ {
+ _name = name;
+ _parameters = parameters;
+
+ _methodInfo = ConditionMethodFactory.CreateConditionMethod(_name);
+ if (_methodInfo == null)
+ {
+ Internal.InternalLogger.Error("Condition method: '{0}' not found", name);
+ throw new ArgumentException("Condition method not found: '" + name + "'");
+ }
+ ParameterInfo[] formalParameters = _methodInfo.GetParameters();
+ if (formalParameters.Length >= 0)
+ {
+ _acceptsLogEvent = (formalParameters[0].ParameterType == typeof(LogEventInfo));
+ }
+ else
+ {
+ _acceptsLogEvent = false;
+ }
+
+ int actualParameterCount = _parameters.Count;
+ if (_acceptsLogEvent)
+ actualParameterCount++;
+ if (formalParameters.Length != actualParameterCount)
+ {
+ Internal.InternalLogger.Error("Condition method: '{0}' expects {1} parameters. Passed {2}", name, formalParameters.Length, actualParameterCount);
+ throw new ConditionParseException(String.Format("Condition method: '{0}' expects {1} parameters. Passed {2}", name, formalParameters.Length, actualParameterCount));
+ }
+ }
+
+ public override object Evaluate(LogEventInfo context)
+ {
+ object[] callParameters;
+ int parameterOffset = _acceptsLogEvent ? 1 : 0;
+
+ callParameters = new object[_parameters.Count + parameterOffset];
+ for (int i = 0; i < _parameters.Count; ++i)
+ {
+ callParameters[i + parameterOffset] = _parameters[i].Evaluate(context);
+ }
+
+ if (_acceptsLogEvent)
+ callParameters[0] = context;
+
+ try
+ {
+ return _methodInfo.Invoke(null, callParameters);
+ }
+ catch (Exception ex)
+ {
+ Internal.InternalLogger.Error("Error: {0}", ex);
+ return "";
+ }
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append(_name);
+ sb.Append("(");
+ for (int i = 0; i < _parameters.Count; ++i)
+ {
+ if (i != 0)
+ sb.Append(",");
+ sb.Append(_parameters[i]);
+ }
+ sb.Append(")");
+ return sb.ToString();
+ }
+
+
+ /// <summary>
+ /// Adds all layouts used by this expression to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ foreach (ConditionExpression expr in _parameters)
+ {
+ expr.PopulateLayouts(layouts);
+ }
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionMethods.cs b/src/NLog/Conditions/ConditionMethods.cs
new file mode 100644
index 0000000..08409c4
--- /dev/null
+++ b/src/NLog/Conditions/ConditionMethods.cs
@@ -0,0 +1,107 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Collections;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// A bunch of utility methods (mostly predicates) which can be used in
+ /// condition expressions. Parially inspired by XPath 1.0.
+ /// </summary>
+ [ConditionMethods]
+ public class ConditionMethods
+ {
+ /// <summary>
+ /// Compares two objects for equality.
+ /// </summary>
+ /// <param name="o1">The first object</param>
+ /// <param name="o2">The second object</param>
+ /// <returns><b>true</b> when two objects are equal, <b>false</b> otherwise.</returns>
+ [ConditionMethod("equals")]
+ public static bool Equals2(object o1, object o2)
+ {
+ return o1.Equals(o2);
+ }
+
+ /// <summary>
+ /// Determines whether the second string is a substring of the first one.
+ /// </summary>
+ /// <param name="s1">The first string</param>
+ /// <param name="s2">The second string</param>
+ /// <returns><b>true</b> when the second string is a substring of the first string, <b>false</b> otherwise.</returns>
+ [ConditionMethod("contains")]
+ public static bool Contains(string s1, string s2)
+ {
+ return s1.IndexOf(s2) >= 0;
+ }
+
+ /// <summary>
+ /// Determines whether the second string is a prefix of the first one.
+ /// </summary>
+ /// <param name="s1">The first string</param>
+ /// <param name="s2">The second string</param>
+ /// <returns><b>true</b> when the second string is a prefix of the first string, <b>false</b> otherwise.</returns>
+ [ConditionMethod("starts-with")]
+ public static bool StartsWith(string s1, string s2)
+ {
+ return s1.StartsWith(s2);
+ }
+
+ /// <summary>
+ /// Determines whether the second string is a suffix of the first one.
+ /// </summary>
+ /// <param name="s1">The first string</param>
+ /// <param name="s2">The second string</param>
+ /// <returns><b>true</b> when the second string is a prefix of the first string, <b>false</b> otherwise.</returns>
+ [ConditionMethod("ends-with")]
+ public static bool EndsWith(string s1, string s2)
+ {
+ return s1.EndsWith(s2);
+ }
+
+ /// <summary>
+ /// Returns the length of a string.
+ /// </summary>
+ /// <param name="s">A string.</param>
+ /// <returns>The length of a string.</returns>
+ [ConditionMethod("length")]
+ public static int Length(string s)
+ {
+ return s.Length;
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionNotExpression.cs b/src/NLog/Conditions/ConditionNotExpression.cs
new file mode 100644
index 0000000..770b07a
--- /dev/null
+++ b/src/NLog/Conditions/ConditionNotExpression.cs
@@ -0,0 +1,71 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Collections;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Condition <b>not</b> expression.
+ /// </summary>
+ internal sealed class ConditionNotExpression : ConditionExpression
+ {
+ private ConditionExpression expr;
+
+ public ConditionNotExpression(ConditionExpression expr)
+ {
+ this.expr = expr;
+ }
+
+ public override object Evaluate(LogEventInfo context)
+ {
+ return !((bool)expr.Evaluate(context));
+ }
+
+ public override string ToString()
+ {
+ return "not(" + expr + ")";
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this expression to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ expr.PopulateLayouts(layouts);
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionOrExpression.cs b/src/NLog/Conditions/ConditionOrExpression.cs
new file mode 100644
index 0000000..e5597af
--- /dev/null
+++ b/src/NLog/Conditions/ConditionOrExpression.cs
@@ -0,0 +1,100 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Collections;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Condition <b>or</b> expression.
+ /// </summary>
+ internal sealed class ConditionOrExpression : ConditionExpression
+ {
+ public readonly ConditionExpression Left;
+ public readonly ConditionExpression Right;
+
+ private static object _boxedFalse = false;
+ private static object _boxedTrue = true;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ConditionOrExpression"/> and assigns
+ /// its Left and Right properties;
+ /// </summary>
+ /// <param name="left">Left hand side of the OR expression.</param>
+ /// <param name="right">Right hand side of the OR expression.</param>
+ public ConditionOrExpression(ConditionExpression left, ConditionExpression right)
+ {
+ this.Left = left;
+ this.Right = right;
+ }
+
+ /// <summary>
+ /// Evaluates the expression by evaluating <see cref="Left"/> and <see cref="Right"/> recursively.
+ /// </summary>
+ /// <param name="context">Evaluation context.</param>
+ /// <returns>The value of the alternative operator.</returns>
+ public override object Evaluate(LogEventInfo context)
+ {
+ bool bval1 = (bool)Left.Evaluate(context);
+ if (bval1)
+ return _boxedTrue;
+
+ bool bval2 = (bool)Right.Evaluate(context);
+ if (bval2)
+ return _boxedTrue;
+
+ return _boxedFalse;
+ }
+
+ /// <summary>
+ /// Returns a string representation of this expression.
+ /// </summary>
+ /// <returns>(Left) or (Right) string</returns>
+ public override string ToString()
+ {
+ return "(" + Left + ") or (" + Right + ")";
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this expression to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ Left.PopulateLayouts(layouts);
+ Right.PopulateLayouts(layouts);
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionParseException.cs b/src/NLog/Conditions/ConditionParseException.cs
new file mode 100644
index 0000000..11a02b9
--- /dev/null
+++ b/src/NLog/Conditions/ConditionParseException.cs
@@ -0,0 +1,76 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+#if !NETCF
+using System.Runtime.Serialization;
+#endif
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Exception during parsing of condition expression
+ /// </summary>
+#if !NETCF
+ [Serializable]
+#endif
+ public class ConditionParseException : Exception
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="ConditionParseException"/>.
+ /// </summary>
+ public ConditionParseException() {}
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ConditionParseException"/>.
+ /// </summary>
+ /// <param name="desc">Error message</param>
+ public ConditionParseException(string desc) : base(desc) {}
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ConditionParseException"/>.
+ /// </summary>
+ /// <param name="desc">Error message</param>
+ /// <param name="inner">Inner exception</param>
+ public ConditionParseException(string desc, Exception inner) : base(desc, inner) {}
+
+#if !NETCF
+ /// <summary>
+ /// Creates a new instance of <see cref="ConditionParseException"/>.
+ /// </summary>
+ /// <param name="info">Serialization info</param>
+ /// <param name="context">Streaming context</param>
+ protected ConditionParseException(SerializationInfo info, StreamingContext context) : base(info, context) {}
+#endif
+ }
+}
diff --git a/src/NLog/Conditions/ConditionParser.cs b/src/NLog/Conditions/ConditionParser.cs
new file mode 100644
index 0000000..4bc98ef
--- /dev/null
+++ b/src/NLog/Conditions/ConditionParser.cs
@@ -0,0 +1,243 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Globalization;
+
+using NLog.Conditions;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Condition parser. Turns a string representation of condition expression
+ /// into an expression tree.
+ /// </summary>
+ public class ConditionParser
+ {
+ private ConditionTokenizer tokenizer = new ConditionTokenizer();
+
+ private ConditionParser(string query)
+ {
+ tokenizer.InitTokenizer(query);
+ }
+
+ private ConditionMethodExpression ParsePredicate(string functionName)
+ {
+ ConditionExpressionCollection par = new ConditionExpressionCollection();
+
+ while (!tokenizer.IsEOF() && tokenizer.TokenType != ConditionTokenType.RightParen)
+ {
+ par.Add(ParseExpression());
+ if (tokenizer.TokenType != ConditionTokenType.Comma)
+ break;
+ tokenizer.GetNextToken();
+ }
+ tokenizer.Expect(ConditionTokenType.RightParen);
+
+ return new ConditionMethodExpression(functionName, par);
+ }
+
+ private ConditionExpression ParseLiteralExpression()
+ {
+ if (tokenizer.IsToken(ConditionTokenType.LeftParen))
+ {
+ tokenizer.GetNextToken();
+ ConditionExpression e = ParseExpression();
+ tokenizer.Expect(ConditionTokenType.RightParen);
+ return e;
+ };
+
+ if (tokenizer.IsNumber())
+ {
+ string numberString = (string)tokenizer.TokenValue;
+ tokenizer.GetNextToken();
+ if (numberString.IndexOf('.') >= 0)
+ {
+ return new ConditionLiteralExpression(Double.Parse(numberString, CultureInfo.InvariantCulture));
+ }
+ else
+ {
+ return new ConditionLiteralExpression(Int32.Parse(numberString, CultureInfo.InvariantCulture));
+ }
+ }
+
+ if (tokenizer.TokenType == ConditionTokenType.String)
+ {
+ ConditionExpression e = new ConditionLayoutExpression(tokenizer.StringTokenValue);
+ tokenizer.GetNextToken();
+ return e;
+ }
+
+ if (tokenizer.TokenType == ConditionTokenType.Keyword)
+ {
+ string keyword = tokenizer.EatKeyword();
+
+ if (0 == String.Compare(keyword, "level", true))
+ return new ConditionLevelExpression();
+
+ if (0 == String.Compare(keyword, "logger", true))
+ return new ConditionLoggerNameExpression();
+
+ if (0 == String.Compare(keyword, "message", true))
+ return new ConditionMessageExpression();
+
+ if (0 == String.Compare(keyword, "loglevel", true))
+ {
+ tokenizer.Expect(ConditionTokenType.Dot);
+ return new ConditionLiteralExpression(LogLevel.FromString(tokenizer.EatKeyword()));
+ }
+
+ if (0 == String.Compare(keyword, "true", true))
+ return new ConditionLiteralExpression(true);
+
+ if (0 == String.Compare(keyword, "false", true))
+ return new ConditionLiteralExpression(false);
+
+ if (tokenizer.TokenType == ConditionTokenType.LeftParen)
+ {
+ tokenizer.GetNextToken();
+
+ ConditionMethodExpression predicateExpression = ParsePredicate(keyword);
+ return predicateExpression;
+ }
+ }
+
+ throw new ConditionParseException("Unexpected token: " + tokenizer.TokenValue);
+ }
+
+ private ConditionExpression ParseBooleanRelation()
+ {
+ ConditionExpression e = ParseLiteralExpression();
+
+ if (tokenizer.IsToken(ConditionTokenType.EQ))
+ {
+ tokenizer.GetNextToken();
+ return new ConditionRelationalExpression(e, ParseLiteralExpression(), ConditionRelationalOperator.Equal);
+ };
+
+ if (tokenizer.IsToken(ConditionTokenType.NE))
+ {
+ tokenizer.GetNextToken();
+ return new ConditionRelationalExpression(e, ParseLiteralExpression(), ConditionRelationalOperator.NotEqual);
+ };
+
+ if (tokenizer.IsToken(ConditionTokenType.LT))
+ {
+ tokenizer.GetNextToken();
+ return new ConditionRelationalExpression(e, ParseLiteralExpression(), ConditionRelationalOperator.Less);
+ };
+
+ if (tokenizer.IsToken(ConditionTokenType.GT))
+ {
+ tokenizer.GetNextToken();
+ return new ConditionRelationalExpression(e, ParseLiteralExpression(), ConditionRelationalOperator.Greater);
+ };
+
+ if (tokenizer.IsToken(ConditionTokenType.LE))
+ {
+ tokenizer.GetNextToken();
+ return new ConditionRelationalExpression(e, ParseLiteralExpression(), ConditionRelationalOperator.LessOrEqual);
+ };
+
+ if (tokenizer.IsToken(ConditionTokenType.GE))
+ {
+ tokenizer.GetNextToken();
+ return new ConditionRelationalExpression(e, ParseLiteralExpression(), ConditionRelationalOperator.GreaterOrEqual);
+ };
+
+ return e;
+ }
+
+ private ConditionExpression ParseBooleanPredicate()
+ {
+ if (tokenizer.IsKeyword("not") || tokenizer.IsToken(ConditionTokenType.Not))
+ {
+ tokenizer.GetNextToken();
+ return new ConditionNotExpression((ConditionExpression)ParseBooleanPredicate());
+ }
+
+ return ParseBooleanRelation();
+ }
+
+ private ConditionExpression ParseBooleanAnd()
+ {
+ ConditionExpression e = ParseBooleanPredicate();
+
+ while (tokenizer.IsKeyword("and") || tokenizer.IsToken(ConditionTokenType.And))
+ {
+ tokenizer.GetNextToken();
+ e = new ConditionAndExpression((ConditionExpression)e, (ConditionExpression)ParseBooleanPredicate());
+ }
+ return e;
+ }
+
+ private ConditionExpression ParseBooleanOr()
+ {
+ ConditionExpression e = ParseBooleanAnd();
+
+ while (tokenizer.IsKeyword("or") || tokenizer.IsToken(ConditionTokenType.Or))
+ {
+ tokenizer.GetNextToken();
+ e = new ConditionOrExpression((ConditionExpression)e, (ConditionExpression)ParseBooleanAnd());
+ }
+ return e;
+ }
+
+ private ConditionExpression ParseBooleanExpression()
+ {
+ return ParseBooleanOr();
+ }
+
+ private ConditionExpression ParseExpression()
+ {
+ return ParseBooleanExpression();
+ }
+
+ /// <summary>
+ /// Parses the specified condition string and turns it into
+ /// <see cref="ConditionExpression"/> tree.
+ /// </summary>
+ /// <param name="expr">The expression to be parsed.</param>
+ /// <returns>The root of the expression syntax tree which can be used to get the value of the condition in a specified context</returns>
+ public static ConditionExpression ParseExpression(string expr)
+ {
+ ConditionParser parser = new ConditionParser(expr);
+ ConditionExpression e = parser.ParseExpression();
+ if (!parser.tokenizer.IsEOF())
+ throw new ConditionParseException("Unexpected token: " + parser.tokenizer.TokenValue);
+ return e;
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionRelationalExpression.cs b/src/NLog/Conditions/ConditionRelationalExpression.cs
new file mode 100644
index 0000000..6339906
--- /dev/null
+++ b/src/NLog/Conditions/ConditionRelationalExpression.cs
@@ -0,0 +1,195 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Collections;
+using System.ComponentModel;
+
+using System.Globalization;
+
+using System.Xml.Serialization;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Condition relational (<b>==</b>, <b>!=</b>, <b><</b>, <b><=</b>,
+ /// <b>></b> or <b>>=</b>) expression.
+ /// </summary>
+ internal sealed class ConditionRelationalExpression : ConditionExpression
+ {
+ public ConditionExpression par1;
+ public ConditionExpression par2;
+ public ConditionRelationalOperator op;
+
+ public ConditionRelationalExpression() {}
+
+ public ConditionRelationalExpression(ConditionExpression par1, ConditionExpression par2, ConditionRelationalOperator op)
+ {
+ this.par1 = par1;
+ this.par2 = par2;
+ this.op = op;
+ }
+
+ private static void PromoteTypes(ref object val1, ref object val2)
+ {
+ if (val1.GetType() == val2.GetType())
+ return;
+
+ if (val1 is DateTime || val2 is DateTime)
+ {
+ val1 = Convert.ToDateTime(val1);
+ val2 = Convert.ToDateTime(val2);
+ return;
+ }
+
+ if (val1 is string || val2 is string)
+ {
+ val1 = Convert.ToString(val1);
+ val2 = Convert.ToString(val2);
+ return;
+ }
+ if (val1 is double || val2 is double)
+ {
+ val1 = Convert.ToDouble(val1);
+ val2 = Convert.ToDouble(val2);
+ return;
+ }
+
+ if (val1 is float || val2 is float)
+ {
+ val1 = Convert.ToSingle(val1);
+ val2 = Convert.ToSingle(val2);
+ return;
+ }
+ if (val1 is decimal || val2 is decimal)
+ {
+ val1 = Convert.ToDecimal(val1);
+ val2 = Convert.ToDecimal(val2);
+ return;
+ }
+ if (val1 is long || val2 is long)
+ {
+ val1 = Convert.ToInt64(val1);
+ val2 = Convert.ToInt64(val2);
+ return;
+ }
+ if (val1 is int || val2 is int)
+ {
+ val1 = Convert.ToInt32(val1);
+ val2 = Convert.ToInt32(val2);
+ return;
+ }
+
+ if (val1 is bool || val2 is bool)
+ {
+ val1 = Convert.ToBoolean(val1);
+ val2 = Convert.ToBoolean(val2);
+ return;
+ }
+ throw new Exception("Cannot promote types " + val1.GetType().Name + " and " + val2.GetType().Name + " to one type.");
+ }
+
+ public static object Compare(object v1, object v2, ConditionRelationalOperator op)
+ {
+ if (v1 == null || v2 == null)
+ return null;
+
+ IComparer comparer = Comparer.Default;
+ PromoteTypes(ref v1, ref v2);
+ switch (op)
+ {
+ case ConditionRelationalOperator.Equal:
+ return comparer.Compare(v1, v2) == 0;
+
+ case ConditionRelationalOperator.NotEqual:
+ return comparer.Compare(v1, v2) != 0;
+
+ case ConditionRelationalOperator.Greater:
+ return comparer.Compare(v1, v2) > 0;
+
+ case ConditionRelationalOperator.GreaterOrEqual:
+ return comparer.Compare(v1, v2) >= 0;
+
+ case ConditionRelationalOperator.LessOrEqual:
+ return comparer.Compare(v1, v2) <= 0;
+
+ case ConditionRelationalOperator.Less:
+ return comparer.Compare(v1, v2) < 0;
+
+ default:
+ throw new NotSupportedException("Relational operator " + op + " is not supported.");
+ }
+ }
+
+ public override object Evaluate(LogEventInfo context)
+ {
+ object v1 = par1.Evaluate(context);
+ object v2 = par2.Evaluate(context);
+
+ return Compare(v1, v2, op);
+ }
+
+ public string OperatorString
+ {
+ get
+ {
+ switch (op)
+ {
+ case ConditionRelationalOperator.Equal: return "==";
+ case ConditionRelationalOperator.NotEqual: return "!=";
+ case ConditionRelationalOperator.Greater: return ">";
+ case ConditionRelationalOperator.Less: return "<";
+ case ConditionRelationalOperator.GreaterOrEqual: return ">=";
+ case ConditionRelationalOperator.LessOrEqual: return "<=";
+ }
+ return "";
+ }
+ }
+
+ public override string ToString()
+ {
+ return par1.ToString() + " " + OperatorString + " " + par2.ToString();
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this expression to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ par1.PopulateLayouts(layouts);
+ par2.PopulateLayouts(layouts);
+ }
+ }
+}
diff --git a/src/NLog/Conditions/ConditionRelationalOperator.cs b/src/NLog/Conditions/ConditionRelationalOperator.cs
new file mode 100644
index 0000000..0aca8c4
--- /dev/null
+++ b/src/NLog/Conditions/ConditionRelationalOperator.cs
@@ -0,0 +1,71 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Relational operators used in conditions.
+ /// </summary>
+ internal enum ConditionRelationalOperator
+ {
+ /// <summary>
+ /// Equality (==)
+ /// </summary>
+ Equal,
+
+ /// <summary>
+ /// Inequality (!=)
+ /// </summary>
+ NotEqual,
+
+ /// <summary>
+ /// Less than (<)
+ /// </summary>
+ Less,
+
+ /// <summary>
+ /// Greater than (>)
+ /// </summary>
+ Greater,
+
+ /// <summary>
+ /// Less than or equal (<=)
+ /// </summary>
+ LessOrEqual,
+
+ /// <summary>
+ /// Greater than or equal (>=)
+ /// </summary>
+ GreaterOrEqual,
+ }
+}
diff --git a/src/NLog/Conditions/ConditionTokenType.cs b/src/NLog/Conditions/ConditionTokenType.cs
new file mode 100644
index 0000000..f109d7b
--- /dev/null
+++ b/src/NLog/Conditions/ConditionTokenType.cs
@@ -0,0 +1,73 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Collections;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Token types for condition expressions.
+ /// </summary>
+ internal enum ConditionTokenType
+ {
+ EOF,
+ BOF,
+ Number,
+ String,
+ Keyword,
+ //Punct,
+ Whitespace,
+
+ FirstPunct,
+
+ LT,
+ GT,
+ LE,
+ GE,
+ EQ,
+ NE,
+ LeftParen,
+ RightParen,
+ Dot,
+ Comma,
+ Not,
+ And,
+ Or,
+
+ LastPunct,
+ Invalid,
+ };
+}
diff --git a/src/NLog/Conditions/ConditionTokenizer.cs b/src/NLog/Conditions/ConditionTokenizer.cs
new file mode 100644
index 0000000..cfbac82
--- /dev/null
+++ b/src/NLog/Conditions/ConditionTokenizer.cs
@@ -0,0 +1,459 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Collections;
+
+namespace NLog.Conditions
+{
+ /// <summary>
+ /// Hand-written tokenizer for conditions.
+ /// </summary>
+ internal sealed class ConditionTokenizer
+ {
+ private string _inputString = null;
+ private int _position = 0;
+ private int _tokenPosition = 0;
+
+ private ConditionTokenType _tokenType;
+ private string _tokenValue;
+ private string _tokenValueLowercase;
+
+ public bool IgnoreWhiteSpace = true;
+
+ public int TokenPosition
+ {
+ get { return _tokenPosition; }
+ }
+
+ public ConditionTokenType TokenType
+ {
+ get { return _tokenType; }
+ set { _tokenType = value; }
+ }
+
+ public string TokenValue
+ {
+ get { return _tokenValue; }
+ }
+
+ public string StringTokenValue
+ {
+ get
+ {
+ string s = _tokenValue;
+
+ return s.Substring(1, s.Length - 2).Replace("''", "'");
+ }
+ }
+
+ public ConditionTokenizer() {}
+
+ void SkipWhitespace()
+ {
+ int ch;
+
+ while ((ch = PeekChar()) != -1)
+ {
+ if (!Char.IsWhiteSpace((char)ch))
+ break;
+ ReadChar();
+ };
+ }
+
+ public void InitTokenizer(string s)
+ {
+ _inputString = s;
+ _position = 0;
+ _tokenType = ConditionTokenType.BOF;
+
+ GetNextToken();
+ }
+
+ int PeekChar()
+ {
+ if (_position < _inputString.Length)
+ {
+ return (int)_inputString[_position];
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ int ReadChar()
+ {
+ if (_position < _inputString.Length)
+ {
+ return (int)_inputString[_position++];
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ public void Expect(ConditionTokenType type)
+ {
+ if (_tokenType != type)
+ throw new ConditionParseException("Expected token of type: " + type + ", got " + _tokenType + " (" + _tokenValue + ").");
+
+ GetNextToken();
+ }
+
+
+ public void ExpectKeyword(string s)
+ {
+ if (_tokenType != ConditionTokenType.Keyword)
+ throw new ConditionParseException("Expected keyword: " + s + ", got " + _tokenType + ".");
+
+ if (_tokenValueLowercase != s)
+ throw new ConditionParseException("Expected keyword: " + s + ", got " + _tokenValueLowercase + ".");
+
+ GetNextToken();
+ }
+
+ public string EatKeyword()
+ {
+ if (_tokenType != ConditionTokenType.Keyword)
+ throw new ConditionParseException("Identifier expected");
+
+ string s = (string)_tokenValue;
+ GetNextToken();
+ return s;
+ }
+
+ public bool IsKeyword(string s)
+ {
+ if (_tokenType != ConditionTokenType.Keyword)
+ return false;
+
+ if (_tokenValueLowercase != s)
+ return false;
+
+ return true;
+ }
+
+ public bool IsKeyword()
+ {
+ if (_tokenType != ConditionTokenType.Keyword)
+ return false;
+
+ return true;
+ }
+
+ public bool IsEOF()
+ {
+ if (_tokenType != ConditionTokenType.EOF)
+ return false;
+ return true;
+ }
+
+ public bool IsNumber()
+ {
+ return _tokenType == ConditionTokenType.Number;
+ }
+
+ public bool IsToken(ConditionTokenType token)
+ {
+ return _tokenType == token;
+ }
+
+ public bool IsToken(object[] tokens)
+ {
+ for (int i = 0; i < tokens.Length; ++i)
+ {
+ if (tokens[i] is string)
+ {
+ if (IsKeyword((string)tokens[i]))
+ return true;
+ }
+ else
+ {
+ if (_tokenType == (ConditionTokenType)tokens[i])
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public bool IsPunctuation()
+ {
+ return (_tokenType >= ConditionTokenType.FirstPunct && _tokenType < ConditionTokenType.LastPunct);
+ }
+
+ struct CharToTokenType
+ {
+ public char ch;
+ public ConditionTokenType tokenType;
+
+ public CharToTokenType(char ch, ConditionTokenType tokenType)
+ {
+ this.ch = ch;
+ this.tokenType = tokenType;
+ }
+ }
+
+ static CharToTokenType[] charToTokenType =
+ {
+ new CharToTokenType('<', ConditionTokenType.LT),
+ new CharToTokenType('>', ConditionTokenType.GT),
+ new CharToTokenType('=', ConditionTokenType.EQ),
+ new CharToTokenType('(', ConditionTokenType.LeftParen),
+ new CharToTokenType(')', ConditionTokenType.RightParen),
+ new CharToTokenType('.', ConditionTokenType.Dot),
+ new CharToTokenType(',', ConditionTokenType.Comma),
+ new CharToTokenType('!', ConditionTokenType.Not),
+ };
+
+ static ConditionTokenType[] charIndexToTokenType = new ConditionTokenType[128];
+
+ static ConditionTokenizer()
+ {
+ for (int i = 0; i < 128; ++i)
+ {
+ charIndexToTokenType[i] = ConditionTokenType.Invalid;
+ };
+
+ foreach (CharToTokenType cht in charToTokenType)
+ {
+ // Console.WriteLine("Setting up {0} to {1}", cht.ch, cht.tokenType);
+ charIndexToTokenType[(int)cht.ch] = cht.tokenType;
+ }
+ }
+
+ public void GetNextToken()
+ {
+ if (_tokenType == ConditionTokenType.EOF)
+ throw new Exception("Cannot read past end of stream.");
+
+ if (IgnoreWhiteSpace)
+ {
+ SkipWhitespace();
+ };
+
+ _tokenPosition = _position;
+
+ int i = PeekChar();
+ if (i == -1)
+ {
+ TokenType = ConditionTokenType.EOF;
+ return ;
+ }
+
+ char ch = (char)i;
+
+ if (!IgnoreWhiteSpace && Char.IsWhiteSpace(ch))
+ {
+ StringBuilder sb = new StringBuilder();
+ int ch2;
+
+ while ((ch2 = PeekChar()) != -1)
+ {
+ if (!Char.IsWhiteSpace((char)ch2))
+ break;
+
+ sb.Append((char)ch2);
+ ReadChar();
+ };
+
+ TokenType = ConditionTokenType.Whitespace;
+ _tokenValue = sb.ToString();
+ return ;
+ }
+
+ if (Char.IsDigit(ch))
+ {
+ TokenType = ConditionTokenType.Number;
+ string s = "";
+
+ s += ch;
+ ReadChar();
+
+ while ((i = PeekChar()) != -1)
+ {
+ ch = (char)i;
+
+ if (Char.IsDigit(ch) || (ch == '.'))
+ {
+ s += (char)ReadChar();
+ }
+ else
+ {
+ break;
+ };
+ };
+
+ _tokenValue = s;
+ return ;
+ }
+
+ if (ch == '\'')
+ {
+ TokenType = ConditionTokenType.String;
+
+ StringBuilder sb = new StringBuilder();
+
+ sb.Append(ch);
+ ReadChar();
+
+ while ((i = PeekChar()) != -1)
+ {
+ ch = (char)i;
+
+ sb.Append((char)ReadChar());
+
+ if (ch == '\'')
+ {
+ if (PeekChar() == (int)'\'')
+ {
+ sb.Append('\'');
+ ReadChar();
+ }
+ else
+ break;
+ }
+ };
+
+ _tokenValue = sb.ToString();
+ return ;
+ }
+
+ if (ch == '_' || Char.IsLetter(ch))
+ {
+ TokenType = ConditionTokenType.Keyword;
+
+ StringBuilder sb = new StringBuilder();
+
+ sb.Append((char)ch);
+
+ ReadChar();
+
+ while ((i = PeekChar()) != -1)
+ {
+ if ((char)i == '_' || (char)i == '-' || Char.IsLetterOrDigit((char)i))
+ {
+ sb.Append((char)ReadChar());
+ }
+ else
+ {
+ break;
+ };
+ };
+
+ _tokenValue = sb.ToString();
+ _tokenValueLowercase = _tokenValue.ToLower();
+ return ;
+ }
+
+ ReadChar();
+ _tokenValue = ch.ToString();
+
+ if (ch == '<' && PeekChar() == (int)'>')
+ {
+ TokenType = ConditionTokenType.NE;
+ _tokenValue = "<>";
+ ReadChar();
+ return ;
+ }
+
+ if (ch == '!' && PeekChar() == (int)'=')
+ {
+ TokenType = ConditionTokenType.NE;
+ _tokenValue = "!=";
+ ReadChar();
+ return ;
+ }
+
+ if (ch == '&' && PeekChar() == (int)'&')
+ {
+ TokenType = ConditionTokenType.And;
+ _tokenValue = "&&";
+ ReadChar();
+ return ;
+ }
+
+ if (ch == '|' && PeekChar() == (int)'|')
+ {
+ TokenType = ConditionTokenType.Or;
+ _tokenValue = "||";
+ ReadChar();
+ return ;
+ }
+
+ if (ch == '<' && PeekChar() == (int)'=')
+ {
+ TokenType = ConditionTokenType.LE;
+ _tokenValue = "<=";
+ ReadChar();
+ return ;
+ }
+
+ if (ch == '>' && PeekChar() == (int)'=')
+ {
+ TokenType = ConditionTokenType.GE;
+ _tokenValue = ">=";
+ ReadChar();
+ return ;
+ }
+
+ if (ch == '=' && PeekChar() == (int)'=')
+ {
+ TokenType = ConditionTokenType.EQ;
+ _tokenValue = "==";
+ ReadChar();
+ return ;
+ }
+
+ if (ch >= 32 && ch < 128)
+ {
+ ConditionTokenType tt = charIndexToTokenType[ch];
+
+ if (tt != ConditionTokenType.Invalid)
+ {
+ TokenType = tt;
+ _tokenValue = new String(ch, 1);
+ return ;
+ }
+ else
+ {
+ throw new Exception("Invalid punctuation: " + ch);
+ }
+ }
+ throw new Exception("Invalid token: " + ch);
+ }
+ }
+}
diff --git a/src/NLog/Config/AcceptsConditionAttribute.cs b/src/NLog/Config/AcceptsConditionAttribute.cs
new file mode 100644
index 0000000..e3a7d55
--- /dev/null
+++ b/src/NLog/Config/AcceptsConditionAttribute.cs
@@ -0,0 +1,49 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Attribute used to mark string parameters that accept conditions.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Property)]
+ public sealed class AcceptsConditionAttribute: Attribute
+ {
+ /// <summary>
+ /// Creates a new instance of AcceptsLayoutAttribute
+ /// </summary>
+ public AcceptsConditionAttribute(){}
+ }
+}
diff --git a/src/NLog/Config/AcceptsLayoutAttribute.cs b/src/NLog/Config/AcceptsLayoutAttribute.cs
new file mode 100644
index 0000000..156d4f7
--- /dev/null
+++ b/src/NLog/Config/AcceptsLayoutAttribute.cs
@@ -0,0 +1,49 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Attribute used to mark string parameters that accept layouts.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Property)]
+ public sealed class AcceptsLayoutAttribute: Attribute
+ {
+ /// <summary>
+ /// Creates a new instance of AcceptsLayoutAttribute
+ /// </summary>
+ public AcceptsLayoutAttribute(){}
+ }
+}
diff --git a/src/NLog/Config/ArrayParameterAttribute.cs b/src/NLog/Config/ArrayParameterAttribute.cs
new file mode 100644
index 0000000..d088f2f
--- /dev/null
+++ b/src/NLog/Config/ArrayParameterAttribute.cs
@@ -0,0 +1,76 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Used to mark configurable parameters which are arrays.
+ /// Specifies the mapping between XML elements and .NET types.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Property)]
+ public sealed class ArrayParameterAttribute: Attribute
+ {
+ private Type _itemType;
+ private string _elementName;
+
+ /// <summary>
+ /// Creates a new instance of ArrayParameterAttribute specifying the
+ /// element type and configuration element name.
+ /// </summary>
+ /// <param name="itemType">The type of the array item</param>
+ /// <param name="elementName">The XML element name that represents the item.</param>
+ public ArrayParameterAttribute(Type itemType, string elementName)
+ {
+ _itemType = itemType;
+ _elementName = elementName;
+ }
+
+ /// <summary>
+ /// The .NET type of the array item
+ /// </summary>
+ public Type ItemType
+ {
+ get { return _itemType; }
+ }
+
+ /// <summary>
+ /// The XML element name.
+ /// </summary>
+ public string ElementName
+ {
+ get { return _elementName; }
+ }
+ }
+}
diff --git a/src/NLog/Config/ConfigSectionHandler.cs b/src/NLog/Config/ConfigSectionHandler.cs
new file mode 100644
index 0000000..7a15347
--- /dev/null
+++ b/src/NLog/Config/ConfigSectionHandler.cs
@@ -0,0 +1,67 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Xml;
+using System.Configuration;
+using System.IO;
+
+using NLog.Internal;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// NLog configuration section handler class for configuring NLog from App.config
+ /// </summary>
+ public class ConfigSectionHandler: IConfigurationSectionHandler
+ {
+ object IConfigurationSectionHandler.Create(object parent, object configContext, XmlNode section)
+ {
+ try
+ {
+ string configFileName = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
+
+ return new XmlLoggingConfiguration((XmlElement)section, configFileName);
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("ConfigSectionHandler error: {0}", ex);
+ throw;
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Config/DefaultParameterAttribute.cs b/src/NLog/Config/DefaultParameterAttribute.cs
new file mode 100644
index 0000000..7f3ed9e
--- /dev/null
+++ b/src/NLog/Config/DefaultParameterAttribute.cs
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Attribute used to mark the default parameters for layout renderers.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Property)]
+ public sealed class DefaultParameterAttribute: Attribute
+ {
+ /// <summary>
+ /// Creates a new DefaultParameterAttribute object.
+ /// </summary>
+ public DefaultParameterAttribute()
+ {
+ }
+ }
+}
diff --git a/src/NLog/Config/LoggingConfiguration.cs b/src/NLog/Config/LoggingConfiguration.cs
new file mode 100644
index 0000000..8e74673
--- /dev/null
+++ b/src/NLog/Config/LoggingConfiguration.cs
@@ -0,0 +1,201 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Xml;
+using System.Globalization;
+using System.Reflection;
+
+using NLog;
+using NLog.Internal;
+using NLog.Targets;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Keeps logging configuration and provides simple API
+ /// to modify it.
+ /// </summary>
+ public class LoggingConfiguration
+ {
+ internal TargetDictionary _targets = new TargetDictionary();
+ internal TargetCollection _aliveTargets = new TargetCollection();
+ private LoggingRuleCollection _loggingRules = new LoggingRuleCollection();
+
+ /// <summary>
+ /// Creates new instance of LoggingConfiguration object.
+ /// </summary>
+ public LoggingConfiguration(){}
+
+ /// <summary>
+ /// Registers the specified target object under a given name.
+ /// </summary>
+ /// <param name="name">Name of the target.</param>
+ /// <param name="target">The target object.</param>
+ public void AddTarget(string name, Target target)
+ {
+ if (name == null)
+ throw new ArgumentException("name", "Target name cannot be null");
+ InternalLogger.Debug("Registering target {0}: {1}", name, target.GetType().FullName);
+ _targets[name.ToLower(CultureInfo.InvariantCulture)] = target;
+ }
+
+ /// <summary>
+ /// Removes the specified named target.
+ /// </summary>
+ /// <param name="name">Name of the target.</param>
+ public void RemoveTarget(string name)
+ {
+ _targets.Remove(name.ToLower(CultureInfo.InvariantCulture));
+ }
+
+ /// <summary>
+ /// Finds the target with the specified name.
+ /// </summary>
+ /// <param name="name">The name of the target to be found.</param>
+ /// <returns>Found target or <see langword="null" /> when the target is not found.</returns>
+ public Target FindTargetByName(string name)
+ {
+ return _targets[name.ToLower(CultureInfo.InvariantCulture)];
+ }
+
+ /// <summary>
+ /// The collection of logging rules
+ /// </summary>
+ public LoggingRuleCollection LoggingRules
+ {
+ get { return _loggingRules; }
+ }
+
+ /// <summary>
+ /// A collection of file names which should be watched for changes by NLog.
+ /// </summary>
+ public virtual ICollection FileNamesToWatch
+ {
+ get { return null; }
+ }
+
+ /// <summary>
+ /// Called by LogManager when one of the log configuration files changes.
+ /// </summary>
+ /// <returns>A new instance of <see cref="LoggingConfiguration" /> that represents the updated configuration.</returns>
+ public virtual LoggingConfiguration Reload()
+ {
+ return this;
+ }
+
+
+ /// <summary>
+ /// Flushes any pending log messages on all appenders.
+ /// </summary>
+ internal void FlushAllTargets(TimeSpan timeout)
+ {
+ foreach (Target target in _targets.Values)
+ {
+ try
+ {
+ target.Flush(timeout);
+
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Error while flushing target: {0} {1}", target.Name, ex);
+ }
+ }
+ }
+
+ internal void InitializeAll()
+ {
+ foreach (LoggingRule r in LoggingRules)
+ {
+ foreach (Target t in r.Targets)
+ {
+ if (!_aliveTargets.Contains(t))
+ _aliveTargets.Add(t);
+ }
+ }
+
+ foreach (Target target in _aliveTargets)
+ {
+ try
+ {
+ target.Initialize();
+
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Error while initializing target: {0} {1}", target.Name, ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns a collection of named targets specified in the configuration.
+ /// </summary>
+ /// <returns>A <see cref="TargetCollection"/> object that contains a list of named targets.</returns>
+ /// <remarks>
+ /// Unnamed targets (such as those wrapped by other targets) are not returned.
+ /// </remarks>
+ public TargetCollection GetConfiguredNamedTargets()
+ {
+ TargetCollection tc = new TargetCollection();
+ foreach (Target t in _targets.Values)
+ {
+ tc.Add(t);
+ }
+ return tc;
+ }
+
+
+ /// <summary>
+ /// Closes all targets and releases any unmanaged resources.
+ /// </summary>
+ public void Close()
+ {
+ InternalLogger.Debug("Closing logging configuration...");
+ foreach (Target target in _aliveTargets)
+ {
+ try
+ {
+ InternalLogger.Debug("Closing target {1} ({0})", target.Name, target.GetType().FullName);
+ target.Close();
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Error while closing target: {0} {1}", target.Name, ex);
+ }
+ }
+ }
+ }
+}
diff --git a/src/NLog/Config/LoggingRule.cs b/src/NLog/Config/LoggingRule.cs
new file mode 100644
index 0000000..4ff5711
--- /dev/null
+++ b/src/NLog/Config/LoggingRule.cs
@@ -0,0 +1,275 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Text;
+using System.Globalization;
+
+using NLog;
+using NLog.Targets;
+using NLog.Filters;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Represents a logging rule. An equivalent of <logger /> configuration element.
+ /// </summary>
+ public class LoggingRule
+ {
+ internal enum MatchMode
+ {
+ All, None, Equals, StartsWith, EndsWith, Contains,
+ }
+
+ private string _loggerNamePattern;
+ private MatchMode _loggerNameMatchMode;
+ private string _loggerNameMatchArgument;
+
+ private bool[]_logLevels = new bool[LogLevel.MaxLevel.Ordinal + 1];
+ private TargetCollection _targets = new TargetCollection();
+ private FilterCollection _filters = new FilterCollection();
+ private LoggingRuleCollection _childRules = new LoggingRuleCollection();
+ private bool _final = false;
+
+ /// <summary>
+ /// Returns a string representation of <see cref="LoggingRule"/>. Used for debugging.
+ /// </summary>
+ /// <returns></returns>
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.AppendFormat(CultureInfo.InvariantCulture, "logNamePattern: ({0}:{1})", _loggerNameMatchArgument, _loggerNameMatchMode);
+ sb.Append(" levels: [ ");
+ for (int i = 0; i < _logLevels.Length; ++i)
+ {
+ if (_logLevels[0])
+ sb.AppendFormat(CultureInfo.InvariantCulture, "{0} ", LogLevel.FromOrdinal(i).ToString());
+ }
+ sb.Append("] appendTo: [ ");
+ foreach (Target app in _targets)
+ {
+ sb.AppendFormat(CultureInfo.InvariantCulture, "{0} ", app.Name);
+ }
+ sb.Append("]");
+ return sb.ToString();
+ }
+
+ /// <summary>
+ /// A collection of targets that should be written to when this rule matches.
+ /// </summary>
+ public TargetCollection Targets
+ {
+ get { return _targets; }
+ }
+
+ /// <summary>
+ /// A collection of child rules to be evaluated when this rule matches.
+ /// </summary>
+ public LoggingRuleCollection ChildRules
+ {
+ get { return _childRules; }
+ }
+
+ /// <summary>
+ /// A collection of filters to be checked before writing to targets.
+ /// </summary>
+ public FilterCollection Filters
+ {
+ get { return _filters; }
+ }
+
+ /// <summary>
+ /// Quit processing any further rule when this one matches.
+ /// </summary>
+ public bool Final
+ {
+ get { return _final; }
+ set { _final = value; }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="LoggingRule"/>.
+ /// </summary>
+ public LoggingRule(){}
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="LoggingRule"/> by
+ /// setting the logger name pattern, minimum logging level and
+ /// the target to be written to when logger name and log level match.
+ /// </summary>
+ /// <param name="loggerNamePattern">Logger name pattern. It may include the '*' wildcard at the beginning, at the end or at both ends.</param>
+ /// <param name="minLevel">Minimum log level needed to trigger this rule.</param>
+ /// <param name="target">Target to be written to when the rule matches.</param>
+ public LoggingRule(string loggerNamePattern, LogLevel minLevel, Target target)
+ {
+ LoggerNamePattern = loggerNamePattern;
+ _targets.Add(target);
+ for (int i = (int)minLevel.Ordinal; i <= (int)LogLevel.MaxLevel.Ordinal; ++i)
+ {
+ EnableLoggingForLevel(LogLevel.FromOrdinal(i));
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="LoggingRule"/> by
+ /// setting the logger name pattern and
+ /// the target to be written to when logger name matches.
+ /// </summary>
+ /// <param name="loggerNamePattern">Logger name pattern. It may include the '*' wildcard at the beginning, at the end or at both ends.</param>
+ /// <param name="target">Target to be written to when the rule matches.</param>
+ /// <remarks>By default no logging levels are defined. You should call <see cref="EnableLoggingForLevel" /> and <see cref="DisableLoggingForLevel"/> to set them.</remarks>
+ public LoggingRule(string loggerNamePattern, Target target)
+ {
+ LoggerNamePattern = loggerNamePattern;
+ _targets.Add(target);
+ }
+
+ /// <summary>
+ /// Enables logging for a particular level.
+ /// </summary>
+ /// <param name="level">Level to be enabled.</param>
+ public void EnableLoggingForLevel(LogLevel level)
+ {
+ _logLevels[level.Ordinal] = true;
+ }
+
+ /// <summary>
+ /// Disables logging for a particular level.
+ /// </summary>
+ /// <param name="level">Level to be disabled.</param>
+ public void DisableLoggingForLevel(LogLevel level)
+ {
+ _logLevels[level.Ordinal] = false;
+ }
+
+ /// <summary>
+ /// Checks whether te particular log level is enabled for this rule.
+ /// </summary>
+ /// <param name="level">Level to be checked</param>
+ /// <returns><see langword="true"/> when the log level is enabled, <see langword="false" /> otherwise.</returns>
+ public bool IsLoggingEnabledForLevel(LogLevel level)
+ {
+ return _logLevels[level.Ordinal];
+ }
+
+ /// <summary>
+ /// Logger name pattern.
+ /// </summary>
+ /// <remarks>
+ /// Logger name pattern. It may include the '*' wildcard at the beginning, at the end or at both ends but not anywhere else.
+ /// </remarks>
+ public string LoggerNamePattern
+ {
+ get { return _loggerNamePattern; }
+ set
+ {
+ _loggerNamePattern = value;
+ int firstPos = _loggerNamePattern.IndexOf('*');
+ int lastPos = _loggerNamePattern.LastIndexOf('*');
+
+ if (firstPos < 0)
+ {
+ _loggerNameMatchMode = MatchMode.Equals;
+ _loggerNameMatchArgument = value;
+ return ;
+ }
+
+ if (firstPos == lastPos)
+ {
+ string before = LoggerNamePattern.Substring(0, firstPos);
+ string after = LoggerNamePattern.Substring(firstPos + 1);
+
+ if (before.Length > 0)
+ {
+ _loggerNameMatchMode = MatchMode.StartsWith;
+ _loggerNameMatchArgument = before;
+ return ;
+ }
+
+ if (after.Length > 0)
+ {
+ _loggerNameMatchMode = MatchMode.EndsWith;
+ _loggerNameMatchArgument = after;
+ return ;
+ }
+ return ;
+ }
+
+ // *text*
+ if (firstPos == 0 && lastPos == LoggerNamePattern.Length - 1)
+ {
+ string text = LoggerNamePattern.Substring(1, LoggerNamePattern.Length - 2);
+ _loggerNameMatchMode = MatchMode.Contains;
+ _loggerNameMatchArgument = text;
+ return ;
+ }
+
+ _loggerNameMatchMode = MatchMode.None;
+ _loggerNameMatchArgument = String.Empty;
+ }
+ }
+
+ /// <summary>
+ /// Checks whether given name matches the logger name pattern.
+ /// </summary>
+ /// <param name="loggerName">String to be matched</param>
+ /// <returns><see langword="true"/> when the name matches, <see langword="false" /> otherwise.</returns>
+ public bool NameMatches(string loggerName)
+ {
+ switch (_loggerNameMatchMode)
+ {
+ case MatchMode.All:
+ return true;
+
+ default:
+ case MatchMode.None:
+ return false;
+
+ case MatchMode.Equals:
+ return String.CompareOrdinal(loggerName, _loggerNameMatchArgument) == 0;
+
+ case MatchMode.StartsWith:
+ return loggerName.StartsWith(_loggerNameMatchArgument);
+
+ case MatchMode.EndsWith:
+ return loggerName.EndsWith(_loggerNameMatchArgument);
+
+ case MatchMode.Contains:
+ return loggerName.IndexOf(_loggerNameMatchArgument) >= 0;
+ }
+ }
+ }
+}
diff --git a/src/NLog/Config/LoggingRuleCollection.cs b/src/NLog/Config/LoggingRuleCollection.cs
new file mode 100644
index 0000000..151ae95
--- /dev/null
+++ b/src/NLog/Config/LoggingRuleCollection.cs
@@ -0,0 +1,247 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Targets;
+using NLog.Filters;
+
+namespace NLog.Config
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A collection of elements of type LoggingRule
+ /// </summary>
+ public class LoggingRuleCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the LoggingRuleCollection class.
+ /// </summary>
+ public LoggingRuleCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the LoggingRuleCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new LoggingRuleCollection.
+ /// </param>
+ public LoggingRuleCollection(LoggingRule[]items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the LoggingRuleCollection class, containing elements
+ /// copied from another instance of LoggingRuleCollection
+ /// </summary>
+ /// <param name="items">
+ /// The LoggingRuleCollection whose elements are to be added to the new LoggingRuleCollection.
+ /// </param>
+ public LoggingRuleCollection(LoggingRuleCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this LoggingRuleCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this LoggingRuleCollection.
+ /// </param>
+ public virtual void AddRange(LoggingRule[]items)
+ {
+ foreach (LoggingRule item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another LoggingRuleCollection to the end of this LoggingRuleCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The LoggingRuleCollection whose elements are to be added to the end of this LoggingRuleCollection.
+ /// </param>
+ public virtual void AddRange(LoggingRuleCollection items)
+ {
+ foreach (LoggingRule item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type LoggingRule to the end of this LoggingRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The LoggingRule to be added to the end of this LoggingRuleCollection.
+ /// </param>
+ public virtual void Add(LoggingRule value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic LoggingRule value is in this LoggingRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The LoggingRule value to locate in this LoggingRuleCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this LoggingRuleCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(LoggingRule value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this LoggingRuleCollection
+ /// </summary>
+ /// <param name="value">
+ /// The LoggingRule value to locate in the LoggingRuleCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(LoggingRule value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the LoggingRuleCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the LoggingRule is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The LoggingRule to insert.
+ /// </param>
+ public virtual void Insert(int index, LoggingRule value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the LoggingRule at the given index in this LoggingRuleCollection.
+ /// </summary>
+ public virtual LoggingRule this[int index]
+ {
+ get { return (LoggingRule)this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific LoggingRule from this LoggingRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The LoggingRule value to remove from this LoggingRuleCollection.
+ /// </param>
+ public virtual void Remove(LoggingRule value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by LoggingRuleCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(LoggingRuleCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ /// Returns the current object.
+ /// </summary>
+ public LoggingRule Current
+ {
+ get { return (LoggingRule)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ /// Returns the current object.
+ /// </summary>
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (LoggingRule)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ /// Advances to the next object.
+ /// </summary>
+ /// <returns>A <see cref="MoveNext"/> result</returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ /// Resets the enumerator.
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this LoggingRuleCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual LoggingRuleCollection.Enumerator GetEnumerator()
+ {
+ return new LoggingRuleCollection.Enumerator(this);
+ }
+ }
+}
diff --git a/src/NLog/Config/NLogConfigurationException.cs b/src/NLog/Config/NLogConfigurationException.cs
new file mode 100644
index 0000000..bf6c52d
--- /dev/null
+++ b/src/NLog/Config/NLogConfigurationException.cs
@@ -0,0 +1,76 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+#if !NETCF
+using System.Runtime.Serialization;
+#endif
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Exception during configuration
+ /// </summary>
+#if !NETCF
+ [Serializable]
+#endif
+ public class NLogConfigurationException : ApplicationException
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="NLogConfigurationException"/>.
+ /// </summary>
+ public NLogConfigurationException() {}
+
+ /// <summary>
+ /// Creates a new instance of <see cref="NLogConfigurationException"/>.
+ /// </summary>
+ /// <param name="desc">Error message</param>
+ public NLogConfigurationException(string desc) : base(desc) {}
+
+ /// <summary>
+ /// Creates a new instance of <see cref="NLogConfigurationException"/>.
+ /// </summary>
+ /// <param name="desc">Error message</param>
+ /// <param name="inner">Inner exception</param>
+ public NLogConfigurationException(string desc, Exception inner) : base(desc, inner) {}
+
+#if !NETCF
+ /// <summary>
+ /// Creates a new instance of <see cref="NLogConfigurationException"/>.
+ /// </summary>
+ /// <param name="info">Serialization info</param>
+ /// <param name="context">Streaming context</param>
+ protected NLogConfigurationException(SerializationInfo info, StreamingContext context) : base(info, context) {}
+#endif
+ }
+}
diff --git a/src/NLog/Config/NotSupportedRuntimeAttribute.cs b/src/NLog/Config/NotSupportedRuntimeAttribute.cs
new file mode 100644
index 0000000..1930761
--- /dev/null
+++ b/src/NLog/Config/NotSupportedRuntimeAttribute.cs
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Marks classes and properties as NOT supporting particular runtime framework
+ /// and operating system.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property,AllowMultiple=true)]
+ public sealed class NotSupportedRuntimeAttribute: SupportedRuntimeAttributeBase
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="SupportedRuntimeAttribute"/>.
+ /// </summary>
+ public NotSupportedRuntimeAttribute()
+ {
+ }
+ }
+}
diff --git a/src/NLog/Config/RequiredParameterAttribute.cs b/src/NLog/Config/RequiredParameterAttribute.cs
new file mode 100644
index 0000000..7ab7631
--- /dev/null
+++ b/src/NLog/Config/RequiredParameterAttribute.cs
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Attribute used to mark the required parameters for targets,
+ /// layout targets and filters.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Property)]
+ public sealed class RequiredParameterAttribute: Attribute
+ {
+ /// <summary>
+ /// Creates a new RequiredParameterAttribute object.
+ /// </summary>
+ public RequiredParameterAttribute()
+ {
+ }
+ }
+}
diff --git a/src/NLog/Config/RuntimeFramework.cs b/src/NLog/Config/RuntimeFramework.cs
new file mode 100644
index 0000000..f3f662e
--- /dev/null
+++ b/src/NLog/Config/RuntimeFramework.cs
@@ -0,0 +1,73 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using NLog.Internal;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Supported runtime frameworks.
+ /// </summary>
+ /// <remarks>
+ /// If you add anything here, make sure to add the appropriate detection
+ /// code to <see cref="PlatformDetector"/>
+ /// </remarks>
+ public enum RuntimeFramework
+ {
+ /// <summary>
+ /// Any framework.
+ /// </summary>
+ Any,
+
+ /// <summary>
+ /// .NET Compact Framework
+ /// </summary>
+ DotNetCompactFramework,
+
+ /// <summary>
+ /// .NET Framework
+ /// </summary>
+ DotNetFramework,
+
+ /// <summary>
+ /// Mono Project
+ /// </summary>
+ Mono,
+
+ /// <summary>
+ /// Unknown
+ /// </summary>
+ Unknown,
+ }
+}
diff --git a/src/NLog/Config/RuntimeOS.cs b/src/NLog/Config/RuntimeOS.cs
new file mode 100644
index 0000000..b550519
--- /dev/null
+++ b/src/NLog/Config/RuntimeOS.cs
@@ -0,0 +1,79 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+using NLog.Internal;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Supported operating systems.
+ /// </summary>
+ /// <remarks>
+ /// If you add anything here, make sure to add the appropriate detection
+ /// code to <see cref="PlatformDetector"/>
+ /// </remarks>
+ public enum RuntimeOS
+ {
+ /// <summary>
+ /// Any operating system.
+ /// </summary>
+ Any,
+
+ /// <summary>
+ /// Unix/Linux operating systems
+ /// </summary>
+ Unix,
+
+ /// <summary>
+ /// Windows CE
+ /// </summary>
+ WindowsCE,
+
+ /// <summary>
+ /// Desktop versions of Windows (95,98,ME)
+ /// </summary>
+ Windows,
+
+ /// <summary>
+ /// Windows NT, 2000, 2003 and future versions based on NT technology
+ /// </summary>
+ WindowsNT,
+
+ /// <summary>
+ /// Unknown operating system
+ /// </summary>
+ Unknown
+ }
+}
diff --git a/src/NLog/Config/SimpleConfigurator.cs b/src/NLog/Config/SimpleConfigurator.cs
new file mode 100644
index 0000000..df0272d
--- /dev/null
+++ b/src/NLog/Config/SimpleConfigurator.cs
@@ -0,0 +1,122 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Targets;
+using NLog.Filters;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Provides simple programmatic configuration API used for trivial logging cases.
+ /// </summary>
+ public class SimpleConfigurator
+ {
+#if !NETCF
+ /// <summary>
+ /// Configures NLog for console logging so that all messages above and including
+ /// the <see cref="LogLevel.Info"/> level are output to the console.
+ /// </summary>
+ public static void ConfigureForConsoleLogging()
+ {
+ ConfigureForConsoleLogging(LogLevel.Info);
+ }
+
+ /// <summary>
+ /// Configures NLog for console logging so that all messages above and including
+ /// the specified level are output to the console.
+ /// </summary>
+ /// <param name="minLevel">The minimal logging level.</param>
+ public static void ConfigureForConsoleLogging(LogLevel minLevel)
+ {
+ ConsoleTarget consoleTarget = new ConsoleTarget();
+
+ LoggingConfiguration config = new LoggingConfiguration();
+ LoggingRule rule = new LoggingRule("*", minLevel, consoleTarget);
+ config.LoggingRules.Add(rule);
+ LogManager.Configuration = config;
+ }
+#endif
+
+ /// <summary>
+ /// Configures NLog for to log to the specified target so that all messages
+ /// above and including the <see cref="LogLevel.Info"/> level are output.
+ /// </summary>
+ /// <param name="target">The target to log all messages to.</param>
+ public static void ConfigureForTargetLogging(Target target)
+ {
+ ConfigureForTargetLogging(target, LogLevel.Info);
+ }
+
+ /// <summary>
+ /// Configures NLog for to log to the specified target so that all messages
+ /// above and including the specified level are output.
+ /// </summary>
+ /// <param name="target">The target to log all messages to.</param>
+ /// <param name="minLevel">The minimal logging level.</param>
+ public static void ConfigureForTargetLogging(Target target, LogLevel minLevel)
+ {
+ LoggingConfiguration config = new LoggingConfiguration();
+ LoggingRule rule = new LoggingRule("*", minLevel, target);
+ config.LoggingRules.Add(rule);
+ LogManager.Configuration = config;
+ }
+
+ /// <summary>
+ /// Configures NLog for file logging so that all messages above and including
+ /// the <see cref="LogLevel.Info"/> level are written to the specified file.
+ /// </summary>
+ /// <param name="fileName">Log file name.</param>
+ public static void ConfigureForFileLogging(string fileName)
+ {
+ ConfigureForFileLogging(fileName, LogLevel.Info);
+ }
+
+ /// <summary>
+ /// Configures NLog for file logging so that all messages above and including
+ /// the specified level are written to the specified file.
+ /// </summary>
+ /// <param name="fileName">Log file name.</param>
+ /// <param name="minLevel">The minimal logging level.</param>
+ public static void ConfigureForFileLogging(string fileName, LogLevel minLevel)
+ {
+ FileTarget target = new FileTarget();
+ target.FileName = fileName;
+ ConfigureForTargetLogging(target, minLevel);
+ }
+ }
+}
diff --git a/src/NLog/Config/SupportedRuntimeAttribute.cs b/src/NLog/Config/SupportedRuntimeAttribute.cs
new file mode 100644
index 0000000..184e3f3
--- /dev/null
+++ b/src/NLog/Config/SupportedRuntimeAttribute.cs
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Marks classes and properties as supporting particular runtime framework
+ /// and operating system.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property,AllowMultiple=true)]
+ public sealed class SupportedRuntimeAttribute: SupportedRuntimeAttributeBase
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="SupportedRuntimeAttribute"/>.
+ /// </summary>
+ public SupportedRuntimeAttribute()
+ {
+ }
+ }
+}
diff --git a/src/NLog/Config/SupportedRuntimeAttributeBase.cs b/src/NLog/Config/SupportedRuntimeAttributeBase.cs
new file mode 100644
index 0000000..fb9e0fd
--- /dev/null
+++ b/src/NLog/Config/SupportedRuntimeAttributeBase.cs
@@ -0,0 +1,113 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// Marks classes and properties as supporting particular runtime framework
+ /// and operating system.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class)]
+ public class SupportedRuntimeAttributeBase: Attribute
+ {
+ private RuntimeFramework _framework = RuntimeFramework.Any;
+ private RuntimeOS _os = RuntimeOS.Any;
+ private string _minRuntimeVersion = null;
+ private string _maxRuntimeVersion = null;
+ private string _minOSVersion = null;
+ private string _maxOSVersion = null;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="SupportedRuntimeAttributeBase"/>.
+ /// </summary>
+ protected SupportedRuntimeAttributeBase()
+ {
+ }
+
+ /// <summary>
+ /// Supported runtime framework.
+ /// </summary>
+ public RuntimeFramework Framework
+ {
+ get { return _framework; }
+ set { _framework = value; }
+ }
+
+ /// <summary>
+ /// Supported operating system.
+ /// </summary>
+ public RuntimeOS OS
+ {
+ get { return _os; }
+ set { _os = value; }
+ }
+
+ /// <summary>
+ /// Minimum runtime version supported.
+ /// </summary>
+ public string MinRuntimeVersion
+ {
+ get { return _minRuntimeVersion; }
+ set { _minRuntimeVersion = value; }
+ }
+
+ /// <summary>
+ /// Maximum runtime version supported.
+ /// </summary>
+ public string MaxRuntimeVersion
+ {
+ get { return _maxRuntimeVersion; }
+ set { _maxRuntimeVersion = value; }
+ }
+
+ /// <summary>
+ /// Minimum operating system version supported.
+ /// </summary>
+ public string MinOSVersion
+ {
+ get { return _minOSVersion; }
+ set { _minOSVersion = value; }
+ }
+
+ /// <summary>
+ /// Maximum operating system version supported.
+ /// </summary>
+ public string MaxOSVersion
+ {
+ get { return _maxOSVersion; }
+ set { _maxOSVersion = value; }
+ }
+ }
+}
diff --git a/src/NLog/Config/XmlLoggingConfiguration.cs b/src/NLog/Config/XmlLoggingConfiguration.cs
new file mode 100644
index 0000000..dc97302
--- /dev/null
+++ b/src/NLog/Config/XmlLoggingConfiguration.cs
@@ -0,0 +1,687 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Xml;
+using System.IO;
+using System.Globalization;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Targets;
+using NLog.Filters;
+using NLog.LayoutRenderers;
+using NLog.Internal;
+using NLog.Targets.Wrappers;
+
+namespace NLog.Config
+{
+ /// <summary>
+ /// A class for configuring NLog through an XML configuration file
+ /// (App.config style or App.nlog style)
+ /// </summary>
+ public class XmlLoggingConfiguration: LoggingConfiguration
+ {
+ private StringDictionary _visitedFile = new StringDictionary();
+#if NET_2_API
+ private NameValueCollection _variables = new NameValueCollection(StringComparer.InvariantCultureIgnoreCase);
+#else
+ private NameValueCollection _variables = new NameValueCollection(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);
+#endif
+
+ private bool _autoReload = false;
+ private string _originalFileName = null;
+
+ /// <summary>
+ /// Gets or sets the value indicating whether the configuration files
+ /// should be watched for changes and reloaded automatically when changed.
+ /// </summary>
+ public bool AutoReload
+ {
+ get { return _autoReload; }
+ set { _autoReload = value; }
+ }
+
+ /// <summary>
+ /// Constructs a new instance of <see cref="XmlLoggingConfiguration" />
+ /// class and reads the configuration from the specified config file.
+ /// </summary>
+ /// <param name="fileName">Configuration file to be read.</param>
+ public XmlLoggingConfiguration(string fileName) : this(fileName, false)
+ {
+ }
+
+ /// <summary>
+ /// Constructs a new instance of <see cref="XmlLoggingConfiguration" />
+ /// class and reads the configuration from the specified config file.
+ /// </summary>
+ /// <param name="fileName">Configuration file to be read.</param>
+ /// <param name="ignoreErrors">Ignore any errors during configuration.</param>
+ public XmlLoggingConfiguration(string fileName, bool ignoreErrors)
+ {
+ InternalLogger.Info("Configuring from {0}...", fileName);
+ _originalFileName = fileName;
+ try
+ {
+ ConfigureFromFile(fileName);
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Error {0}...", ex);
+ if (!ignoreErrors)
+ throw new NLogConfigurationException("Exception occured when loading configuration from '" + fileName + "'", ex);
+ }
+ }
+
+ /// <summary>
+ /// Constructs a new instance of <see cref="XmlLoggingConfiguration" />
+ /// class and reads the configuration from the specified XML element.
+ /// </summary>
+ /// <param name="configElement"><see cref="XmlElement" /> containing the configuration section.</param>
+ /// <param name="fileName">Name of the file that contains the element (to be used as a base for including other files).</param>
+ public XmlLoggingConfiguration(XmlElement configElement, string fileName) : this(configElement, fileName, false)
+ {
+ }
+
+ /// <summary>
+ /// Constructs a new instance of <see cref="XmlLoggingConfiguration" />
+ /// class and reads the configuration from the specified XML element.
+ /// </summary>
+ /// <param name="configElement"><see cref="XmlElement" /> containing the configuration section.</param>
+ /// <param name="fileName">Name of the file that contains the element (to be used as a base for including other files).</param>
+ /// <param name="ignoreErrors">Ignore any errors during configuration.</param>
+ public XmlLoggingConfiguration(XmlElement configElement, string fileName, bool ignoreErrors)
+ {
+ try
+ {
+ if (fileName != null)
+ {
+ InternalLogger.Info("Configuring from an XML element in {0}...", fileName);
+ string key = Path.GetFullPath(fileName).ToLower(CultureInfo.InvariantCulture);
+ _visitedFile[key] = key;
+
+ _originalFileName = fileName;
+ ConfigureFromXmlElement(configElement, Path.GetDirectoryName(fileName));
+ }
+ else
+ {
+ ConfigureFromXmlElement(configElement, null);
+ }
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Error {0}...", ex);
+ if (!ignoreErrors)
+ throw new NLogConfigurationException("Exception occured when loading configuration from XML Element in " + fileName, ex);
+ }
+ }
+
+ /// <summary>
+ /// Gets the collection of file names which should be watched for changes by NLog.
+ /// This is the list of configuration files processed.
+ /// If the <c>autoReload</c> attribute is not set it returns null.
+ /// </summary>
+ public override ICollection FileNamesToWatch
+ {
+ get
+ {
+ if (_autoReload)
+ return _visitedFile.Keys;
+ else
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Re-reads the original configuration file and returns the new <see cref="LoggingConfiguration" /> object.
+ /// </summary>
+ /// <returns>The new <see cref="XmlLoggingConfiguration" /> object.</returns>
+ public override LoggingConfiguration Reload()
+ {
+ return new XmlLoggingConfiguration(_originalFileName);
+ }
+
+ private void ConfigureFromFile(string fileName)
+ {
+ string key = Path.GetFullPath(fileName).ToLower(CultureInfo.InvariantCulture);
+ if (_visitedFile.ContainsKey(key))
+ return ;
+
+ _visitedFile[key] = key;
+
+ XmlDocument doc = new XmlDocument();
+ doc.Load(fileName);
+ if (EqualsCI(doc.DocumentElement.LocalName,"configuration"))
+ {
+ foreach (XmlElement el in doc.DocumentElement.GetElementsByTagName("nlog"))
+ {
+ ConfigureFromXmlElement(el, Path.GetDirectoryName(fileName));
+ }
+ }
+ else
+ {
+ ConfigureFromXmlElement(doc.DocumentElement, Path.GetDirectoryName(fileName));
+ }
+ }
+
+ private static bool EqualsCI(string p1, string p2)
+ {
+ return PropertyHelper.EqualsCI(p1, p2);
+ }
+
+ private string GetCaseInsensitiveAttribute(XmlElement element, string name)
+ {
+ return PropertyHelper.GetCaseInsensitiveAttribute(element, name, _variables);
+ }
+
+ private static bool HasCaseInsensitiveAttribute(XmlElement element, string name)
+ {
+ return PropertyHelper.HasCaseInsensitiveAttribute(element, name);
+ }
+
+ private void IncludeFileFromElement(XmlElement includeElement, string baseDirectory)
+ {
+ string newFileName = Layout.Evaluate(GetCaseInsensitiveAttribute(includeElement, "file"));
+ newFileName = Path.Combine(baseDirectory, newFileName);
+
+ try
+ {
+ if (File.Exists(newFileName))
+ {
+ InternalLogger.Debug("Including file '{0}'", newFileName);
+ ConfigureFromFile(newFileName);
+ }
+ else
+ {
+ throw new FileNotFoundException("Included file not found: " + newFileName);
+ }
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Error when including '{0}' {1}", newFileName, ex);
+
+ if (EqualsCI(GetCaseInsensitiveAttribute(includeElement, "ignoreErrors"), "true"))
+ return;
+ throw new NLogConfigurationException("Error when including: " + newFileName, ex);
+ }
+ }
+
+ private void ConfigureFromXmlElement(XmlElement configElement, string baseDirectory)
+ {
+ switch (GetCaseInsensitiveAttribute(configElement, "autoReload"))
+ {
+ case "true":
+ AutoReload = true;
+ break;
+
+ case "false":
+ AutoReload = false;
+ break;
+ }
+
+ switch (GetCaseInsensitiveAttribute(configElement, "throwExceptions"))
+ {
+ case "true":
+ LogManager.ThrowExceptions = true;
+ break;
+
+ case "false":
+ LogManager.ThrowExceptions = false;
+ break;
+ }
+
+ switch (GetCaseInsensitiveAttribute(configElement, "internalLogToConsole"))
+ {
+ case "true":
+ InternalLogger.LogToConsole = true;
+ break;
+
+ case "false":
+ InternalLogger.LogToConsole = false;
+ break;
+ }
+
+#if !NETCF
+ switch (GetCaseInsensitiveAttribute(configElement, "internalLogToConsoleError"))
+ {
+ case "true":
+ InternalLogger.LogToConsoleError = true;
+ break;
+
+ case "false":
+ InternalLogger.LogToConsoleError = false;
+ break;
+ }
+#endif
+
+ string s = GetCaseInsensitiveAttribute(configElement, "internalLogFile");
+ if (s != null)
+ InternalLogger.LogFile = s;
+
+ s = GetCaseInsensitiveAttribute(configElement, "internalLogLevel");
+ if (s != null)
+ InternalLogger.LogLevel = LogLevel.FromString(s);
+
+ s = GetCaseInsensitiveAttribute(configElement, "globalThreshold");
+ if (s != null)
+ LogManager.GlobalThreshold = LogLevel.FromString(s);
+
+ foreach (XmlElement el in PropertyHelper.GetChildElements(configElement))
+ {
+ switch (el.LocalName.ToLower())
+ {
+ case "extensions":
+ AddExtensionsFromElement(el, baseDirectory);
+ break;
+
+ case "include":
+ IncludeFileFromElement(el, baseDirectory);
+ break;
+
+ case "appenders":
+ case "targets":
+ ConfigureTargetsFromElement(el);
+ break;
+
+ case "variable":
+ SetVariable(el);
+ break;
+
+ case "rules":
+ ConfigureRulesFromElement(this, LoggingRules, el);
+ break;
+ }
+ }
+ }
+
+ private void SetVariable(XmlElement el)
+ {
+ string name = GetCaseInsensitiveAttribute(el, "name");
+ string value = GetCaseInsensitiveAttribute(el, "value");
+
+ _variables[name] = value;
+ }
+
+#if !NETCF
+ /// <summary>
+ /// Gets the default <see cref="LoggingConfiguration" /> object by parsing
+ /// the application configuration file (<c>app.exe.config</c>).
+ /// </summary>
+ public static LoggingConfiguration AppConfig
+ {
+ get
+ {
+#if NET_2_API
+ object o = System.Configuration.ConfigurationManager.GetSection("nlog");
+#else
+ object o = System.Configuration.ConfigurationSettings.GetConfig("nlog");
+#endif
+ return o as LoggingConfiguration;
+ }
+ }
+#endif
+
+ // implementation details
+
+ private static string CleanWhitespace(string s)
+ {
+ s = s.Replace(" ", ""); // get rid of the whitespace
+ return s;
+ }
+
+ private void ConfigureRulesFromElement(LoggingConfiguration config, LoggingRuleCollection rules, XmlElement element)
+ {
+ if (element == null)
+ return ;
+
+ foreach (XmlElement el in PropertyHelper.GetChildElements(element, "logger"))
+ {
+ XmlElement ruleElement = el;
+
+ LoggingRule rule = new LoggingRule();
+ string namePattern = GetCaseInsensitiveAttribute(ruleElement, "name");
+ if (namePattern == null)
+ namePattern = "*";
+
+ string appendTo = GetCaseInsensitiveAttribute(ruleElement, "appendTo");
+ if (appendTo == null)
+ appendTo = GetCaseInsensitiveAttribute(ruleElement, "writeTo");
+
+ rule.LoggerNamePattern = namePattern;
+ if (appendTo != null)
+ {
+ foreach (string t in appendTo.Split(','))
+ {
+ string targetName = t.Trim();
+ Target target = config.FindTargetByName(targetName);
+
+ if (target != null)
+ {
+ rule.Targets.Add(target);
+ }
+ else
+ {
+ throw new NLogConfigurationException("Target " + targetName + " not found.");
+ }
+ }
+ }
+ rule.Final = false;
+
+ if (HasCaseInsensitiveAttribute(ruleElement, "final"))
+ {
+ rule.Final = true;
+ }
+
+ if (HasCaseInsensitiveAttribute(ruleElement, "level"))
+ {
+ LogLevel level = LogLevel.FromString(GetCaseInsensitiveAttribute(ruleElement, "level"));
+ rule.EnableLoggingForLevel(level);
+ }
+ else if (HasCaseInsensitiveAttribute(ruleElement, "levels"))
+ {
+ string levelsString = GetCaseInsensitiveAttribute(ruleElement, "levels");
+ levelsString = CleanWhitespace(levelsString);
+
+ string[]tokens = levelsString.Split(',');
+ foreach (string s in tokens)
+ {
+ if (s != "")
+ {
+ LogLevel level = LogLevel.FromString(s);
+ rule.EnableLoggingForLevel(level);
+ }
+ }
+ }
+ else
+ {
+ int minLevel = 0;
+ int maxLevel = LogLevel.MaxLevel.Ordinal;
+
+ if (HasCaseInsensitiveAttribute(ruleElement, "minlevel"))
+ {
+ minLevel = LogLevel.FromString(GetCaseInsensitiveAttribute(ruleElement, "minlevel")).Ordinal;
+ }
+
+ if (HasCaseInsensitiveAttribute(ruleElement, "maxlevel"))
+ {
+ maxLevel = LogLevel.FromString(GetCaseInsensitiveAttribute(ruleElement, "maxlevel")).Ordinal;
+ }
+
+ for (int i = minLevel; i <= maxLevel; ++i)
+ {
+ rule.EnableLoggingForLevel(LogLevel.FromOrdinal(i));
+ }
+ }
+
+ foreach (XmlElement el2 in PropertyHelper.GetChildElements(ruleElement,"filters"))
+ {
+ ConfigureRuleFiltersFromXmlElement(rule, el2);
+ }
+
+ ConfigureRulesFromElement(config, rule.ChildRules, ruleElement);
+
+ rules.Add(rule);
+ }
+ }
+
+ private void AddExtensionsFromElement(XmlElement element, string baseDirectory)
+ {
+ if (element == null)
+ return ;
+
+ foreach (XmlElement targetElement in PropertyHelper.GetChildElements(element))
+ {
+ if (EqualsCI(targetElement.LocalName,"add"))
+ {
+ string assemblyFile = GetCaseInsensitiveAttribute(targetElement, "assemblyFile");
+ string extPrefix = GetCaseInsensitiveAttribute(targetElement, "prefix");
+ string prefix;
+ if (extPrefix != null && extPrefix.Length != 0)
+ {
+ prefix = extPrefix + ".";
+ }
+ else
+ {
+ prefix = String.Empty;
+ }
+
+ if (assemblyFile != null && assemblyFile.Length > 0)
+ {
+ try
+ {
+ string fullFileName = Path.Combine(baseDirectory, assemblyFile);
+ InternalLogger.Info("Loading assemblyFile: {0}", fullFileName);
+ Assembly asm = Assembly.LoadFrom(fullFileName);
+
+ TargetFactory.AddTargetsFromAssembly(asm, prefix);
+ LayoutRendererFactory.AddLayoutRenderersFromAssembly(asm, prefix);
+ FilterFactory.AddFiltersFromAssembly(asm, prefix);
+ LayoutFactory.AddLayoutsFromAssembly(asm, prefix);
+ ConditionMethodFactory.AddConditionMethodsFromAssembly(asm, prefix);
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Error loading extensions: {0}", ex);
+ if (LogManager.ThrowExceptions)
+ throw new NLogConfigurationException("Error loading extensions: " + assemblyFile, ex);
+ }
+ continue;
+ };
+
+ string assemblyName = GetCaseInsensitiveAttribute(targetElement, "assembly");
+
+ if (assemblyName != null && assemblyName.Length > 0)
+ {
+ try
+ {
+ InternalLogger.Info("Loading assemblyName: {0}", assemblyName);
+ Assembly asm = Assembly.Load(assemblyName);
+
+ TargetFactory.AddTargetsFromAssembly(asm, prefix);
+ LayoutRendererFactory.AddLayoutRenderersFromAssembly(asm, prefix);
+ FilterFactory.AddFiltersFromAssembly(asm, prefix);
+ LayoutFactory.AddLayoutsFromAssembly(asm, prefix);
+ ConditionMethodFactory.AddConditionMethodsFromAssembly(asm, prefix);
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Error loading extensions: {0}", ex);
+ if (LogManager.ThrowExceptions)
+ throw new NLogConfigurationException("Error loading extensions: " + assemblyName, ex);
+ }
+ continue;
+ };
+ }
+
+ }
+ }
+
+ private Target WrapWithAsyncTarget(Target t)
+ {
+ NLog.Targets.Wrappers.AsyncTargetWrapper atw = new NLog.Targets.Wrappers.AsyncTargetWrapper();
+ atw.WrappedTarget = t;
+ atw.Name = t.Name;
+ t.Name = t.Name + "_wrapped";
+ InternalLogger.Debug("Wrapping target '{0}' with AsyncTargetWrapper and renaming to '{1}", atw.Name, t.Name);
+ return atw;
+ }
+
+ private Target WrapWithDefaultWrapper(Target t, XmlElement defaultWrapperElement)
+ {
+ string wrapperType = GetCaseInsensitiveAttribute(defaultWrapperElement, "type");
+ Target wrapperTargetInstance = TargetFactory.CreateTarget(wrapperType);
+ WrapperTargetBase wtb = wrapperTargetInstance as WrapperTargetBase;
+ if (wtb == null)
+ throw new NLogConfigurationException("Target type specified on <default-wrapper /> is not a wrapper.");
+ ConfigureTargetFromXmlElement(wrapperTargetInstance, defaultWrapperElement);
+ while (wtb.WrappedTarget != null)
+ {
+ wtb = wtb.WrappedTarget as WrapperTargetBase;
+ if (wtb == null)
+ throw new NLogConfigurationException("Child target type specified on <default-wrapper /> is not a wrapper.");
+ }
+ wtb.WrappedTarget = t;
+ wrapperTargetInstance.Name = t.Name;
+ t.Name = t.Name + "_wrapped";
+
+ InternalLogger.Debug("Wrapping target '{0}' with '{1}' and renaming to '{2}", wrapperTargetInstance.Name, wrapperTargetInstance.GetType().Name, t.Name);
+ return wrapperTargetInstance;
+ }
+
+ private void ConfigureTargetsFromElement(XmlElement element)
+ {
+ if (element == null)
+ return ;
+
+ bool asyncWrap = EqualsCI(GetCaseInsensitiveAttribute(element, "async"),"true");
+ XmlElement defaultWrapperElement = null;
+ Hashtable typeNameToDefaultTargetParametersElement = new Hashtable();
+
+ foreach (XmlElement targetElement in PropertyHelper.GetChildElements(element))
+ {
+ string name = targetElement.LocalName.ToLower();
+ string type = GetCaseInsensitiveAttribute(targetElement, "type");
+
+ switch (name)
+ {
+ case "default-wrapper":
+ defaultWrapperElement = targetElement;
+ break;
+
+ case "default-target-parameters":
+ typeNameToDefaultTargetParametersElement[type] = targetElement;
+ break;
+
+ case "target":
+ case "appender":
+ case "wrapper":
+ case "wrapper-target":
+ case "compound-target":
+ Target newTarget = TargetFactory.CreateTarget(type);
+
+ XmlElement defaultParametersElement = typeNameToDefaultTargetParametersElement[type] as XmlElement;
+ if (defaultParametersElement != null)
+ ConfigureTargetFromXmlElement(newTarget, defaultParametersElement);
+
+ ConfigureTargetFromXmlElement(newTarget, targetElement);
+
+ if (asyncWrap)
+ newTarget = WrapWithAsyncTarget(newTarget);
+
+ if (defaultWrapperElement != null)
+ newTarget = WrapWithDefaultWrapper(newTarget, defaultWrapperElement);
+
+ InternalLogger.Info("Adding target {0}", newTarget);
+ AddTarget(newTarget.Name, newTarget);
+ break;
+ }
+ }
+ }
+
+ private void ConfigureRuleFiltersFromXmlElement(LoggingRule rule, XmlElement element)
+ {
+ if (element == null)
+ return ;
+
+ foreach (XmlElement el in PropertyHelper.GetChildElements(element))
+ {
+ string name = el.LocalName;
+
+ Filter filter = FilterFactory.CreateFilter(name);
+ PropertyHelper.ConfigureObjectFromAttributes(filter, el.Attributes, _variables, false);
+ rule.Filters.Add(filter);
+ }
+ }
+
+ private void ConfigureTargetFromXmlElement(Target target, XmlElement element)
+ {
+ NLog.Targets.Compound.CompoundTargetBase compound = target as NLog.Targets.Compound.CompoundTargetBase;
+ NLog.Targets.Wrappers.WrapperTargetBase wrapper = target as NLog.Targets.Wrappers.WrapperTargetBase;
+
+ PropertyHelper.ConfigureObjectFromAttributes(target, element.Attributes, _variables, true);
+
+ foreach (XmlElement el in PropertyHelper.GetChildElements(element))
+ {
+ string name = el.LocalName;
+
+ if (compound != null)
+ {
+ if ((name == "target" || name == "wrapper" || name == "wrapper-target" || name == "compound-target"))
+ {
+ string type = GetCaseInsensitiveAttribute(el, "type");
+ Target newTarget = TargetFactory.CreateTarget(type);
+ if (newTarget != null)
+ {
+ ConfigureTargetFromXmlElement(newTarget, el);
+ if (newTarget.Name != null)
+ {
+ // if the new target has name, register it
+ AddTarget(newTarget.Name, newTarget);
+ }
+ compound.Targets.Add(newTarget);
+ }
+ continue;
+ }
+ }
+
+ if (wrapper != null)
+ {
+ if ((name == "target" || name == "wrapper" || name == "wrapper-target" || name == "compound-target"))
+ {
+ string type = GetCaseInsensitiveAttribute(el, "type");
+ Target newTarget = TargetFactory.CreateTarget(type);
+ if (newTarget != null)
+ {
+ ConfigureTargetFromXmlElement(newTarget, el);
+ if (newTarget.Name != null)
+ {
+ // if the new target has name, register it
+ AddTarget(newTarget.Name, newTarget);
+ }
+ if (wrapper.WrappedTarget != null)
+ {
+ throw new NLogConfigurationException("Wrapped target already defined.");
+ }
+ wrapper.WrappedTarget = newTarget;
+ }
+ continue;
+ }
+ }
+
+ PropertyHelper.SetPropertyFromElement(target, el, _variables);
+ }
+ }
+ }
+}
diff --git a/src/NLog/Filter.cs b/src/NLog/Filter.cs
new file mode 100644
index 0000000..80887ab
--- /dev/null
+++ b/src/NLog/Filter.cs
@@ -0,0 +1,97 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+
+using NLog.Config;
+
+namespace NLog
+{
+ /// <summary>
+ /// An abstract filter class. Provides a way to eliminate log messages
+ /// based on properties other than logger name and log level.
+ /// </summary>
+ public abstract class Filter
+ {
+ /// <summary>
+ ///
+ /// </summary>
+ protected Filter(){}
+
+ private FilterResult _filterResult = FilterResult.Neutral;
+
+ /// <summary>
+ /// The <see cref="FilterResult"/> value that should be returned
+ /// when this filter matches.
+ /// </summary>
+ protected FilterResult Result
+ {
+ get { return _filterResult; }
+ }
+
+ /// <summary>
+ /// User-requested action to be taken when filter matches.
+ /// </summary>
+ /// <remarks>
+ /// Allowed values are <c>log</c>, <c>ignore</c>, <c>neutral</c>.
+ /// </remarks>
+ [RequiredParameter]
+ public FilterResult Action
+ {
+ get { return _filterResult; }
+ set { _filterResult = value; }
+ }
+
+ /// <summary>
+ /// Checks whether log event should be logged or not.
+ /// </summary>
+ /// <param name="logEvent">Log event.</param>
+ /// <returns>
+ /// <see cref="FilterResult.Ignore"/> - if the log event should be ignored<br/>
+ /// <see cref="FilterResult.Neutral"/> - if the filter doesn't want to decide<br/>
+ /// <see cref="FilterResult.Log"/> - if the log event should be logged<br/>
+ /// </returns>
+ protected internal abstract FilterResult Check(LogEventInfo logEvent);
+
+ /// <summary>
+ /// Determines whether stack trace information should be gathered
+ /// during log event processing.
+ /// </summary>
+ /// <returns>0 - don't include stack trace<br/>1 - include stack trace without source file information<br/>2 - include full stack trace</returns>
+ public virtual int NeedsStackTrace()
+ {
+ return 0;
+ }
+ }
+}
diff --git a/src/NLog/FilterAttribute.cs b/src/NLog/FilterAttribute.cs
new file mode 100644
index 0000000..7648988
--- /dev/null
+++ b/src/NLog/FilterAttribute.cs
@@ -0,0 +1,64 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog
+{
+ /// <summary>
+ /// Marks class as a layout renderer and assigns a name to it
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class)]
+ public sealed class FilterAttribute: Attribute
+ {
+ private string _name;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="FilterAttribute"/> and assigns
+ /// a name to it.
+ /// </summary>
+ /// <param name="name"></param>
+ public FilterAttribute(string name)
+ {
+ _name = name;
+ }
+
+ /// <summary>
+ /// The name of the filter.
+ /// </summary>
+ public string Name
+ {
+ get { return _name; }
+ }
+ }
+}
diff --git a/src/NLog/FilterCollection.cs b/src/NLog/FilterCollection.cs
new file mode 100644
index 0000000..e057a5f
--- /dev/null
+++ b/src/NLog/FilterCollection.cs
@@ -0,0 +1,243 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace NLog
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A collection of elements of type Filter
+ /// </summary>
+ public class FilterCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the FilterCollection class.
+ /// </summary>
+ public FilterCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the FilterCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new FilterCollection.
+ /// </param>
+ public FilterCollection(Filter[]items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the FilterCollection class, containing elements
+ /// copied from another instance of FilterCollection
+ /// </summary>
+ /// <param name="items">
+ /// The FilterCollection whose elements are to be added to the new FilterCollection.
+ /// </param>
+ public FilterCollection(FilterCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this FilterCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this FilterCollection.
+ /// </param>
+ public virtual void AddRange(Filter[]items)
+ {
+ foreach (Filter item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another FilterCollection to the end of this FilterCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The FilterCollection whose elements are to be added to the end of this FilterCollection.
+ /// </param>
+ public virtual void AddRange(FilterCollection items)
+ {
+ foreach (Filter item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type Filter to the end of this FilterCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The Filter to be added to the end of this FilterCollection.
+ /// </param>
+ public virtual void Add(Filter value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic Filter value is in this FilterCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The Filter value to locate in this FilterCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this FilterCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(Filter value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this FilterCollection
+ /// </summary>
+ /// <param name="value">
+ /// The Filter value to locate in the FilterCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(Filter value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the FilterCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the Filter is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The Filter to insert.
+ /// </param>
+ public virtual void Insert(int index, Filter value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the Filter at the given index in this FilterCollection.
+ /// </summary>
+ public virtual Filter this[int index]
+ {
+ get { return (Filter)this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific Filter from this FilterCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The Filter value to remove from this FilterCollection.
+ /// </param>
+ public virtual void Remove(Filter value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by FilterCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(FilterCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public Filter Current
+ {
+ get { return (Filter)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (Filter)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this FilterCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual FilterCollection.Enumerator GetEnumerator()
+ {
+ return new FilterCollection.Enumerator(this);
+ }
+ }
+}
diff --git a/src/NLog/FilterFactory.cs b/src/NLog/FilterFactory.cs
new file mode 100644
index 0000000..9524b54
--- /dev/null
+++ b/src/NLog/FilterFactory.cs
@@ -0,0 +1,143 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Reflection;
+using System.Globalization;
+
+using NLog.Internal;
+
+namespace NLog
+{
+ /// <summary>
+ /// A factory of logging filters. Creates new filters based on their names.
+ /// </summary>
+ public sealed class FilterFactory
+ {
+ private static TypeDictionary _filters = new TypeDictionary();
+
+ static FilterFactory()
+ {
+ foreach (Assembly a in ExtensionUtils.GetExtensionAssemblies())
+ {
+ AddFiltersFromAssembly(a, "");
+ }
+ }
+
+ private FilterFactory(){}
+
+ /// <summary>
+ /// Removes all filter information from the factory.
+ /// </summary>
+ public static void Clear()
+ {
+ _filters.Clear();
+ }
+
+ /// <summary>
+ /// Scans the specified assembly for types marked with <see cref="FilterAttribute" /> and adds
+ /// them to the factory. Optionally it prepends the specified text to filter names to avoid
+ /// naming collisions.
+ /// </summary>
+ /// <param name="theAssembly">The assembly to be scanned for filters.</param>
+ /// <param name="prefix">The prefix to be prepended to filter names.</param>
+ public static void AddFiltersFromAssembly(Assembly theAssembly, string prefix)
+ {
+ try
+ {
+ InternalLogger.Debug("AddFiltersFromAssembly('{0}')", theAssembly.FullName);
+ foreach (Type t in theAssembly.GetTypes())
+ {
+ FilterAttribute[]attributes = (FilterAttribute[])t.GetCustomAttributes(typeof(FilterAttribute), false);
+ if (attributes != null)
+ {
+ foreach (FilterAttribute attr in attributes)
+ {
+ if (PlatformDetector.IsSupportedOnCurrentRuntime(t))
+ {
+ AddFilter(prefix + attr.Name, t);
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Failed to add filters from '" + theAssembly.FullName + "': {0}", ex);
+ }
+
+ }
+
+ /// <summary>
+ /// Registers the specified filter type to the factory under a specified name.
+ /// </summary>
+ /// <param name="name">The name of the filter (e.g. <code>whenEquals</code> or <code>whenContains</code>)</param>
+ /// <param name="t">The type of the new filter</param>
+ /// <remarks>
+ /// The name specified in the name parameter can then be used
+ /// to create filters.
+ /// </remarks>
+ public static void AddFilter(string name, Type t)
+ {
+ InternalLogger.Trace("Registering filter {0} for type '{1}')", name, t.FullName);
+ _filters[name.ToLower(CultureInfo.InvariantCulture)] = t;
+ }
+
+ /// <summary>
+ /// Creates the filter object based on its filter name.
+ /// </summary>
+ /// <param name="name">The name of the filter (e.g. <code>whenEquals</code> or <code>whenNotEqual</code>)</param>
+ /// <returns>A new instance of the <see cref="Filter"/> object.</returns>
+ public static Filter CreateFilter(string name)
+ {
+ Type t = _filters[name.ToLower(CultureInfo.InvariantCulture)];
+ if (t != null)
+ {
+ Filter la = FactoryHelper.CreateInstance(t) as Filter;
+ if (la != null)
+ return la;
+ }
+ throw new ArgumentException("Filter " + name + " not found.");
+ }
+
+ /// <summary>
+ /// Collection of filter types added to the factory.
+ /// </summary>
+ public static ICollection FilterTypes
+ {
+ get { return _filters.Values; }
+ }
+ }
+}
diff --git a/src/NLog/FilterResult.cs b/src/NLog/FilterResult.cs
new file mode 100644
index 0000000..dffc40f
--- /dev/null
+++ b/src/NLog/FilterResult.cs
@@ -0,0 +1,66 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+namespace NLog
+{
+ /// <summary>
+ /// Filter result.
+ /// </summary>
+ public enum FilterResult
+ {
+ /// <summary>
+ /// The filter doesn't want to decide whether to log or discard the message.
+ /// </summary>
+ Neutral,
+
+ /// <summary>
+ /// The message should be logged.
+ /// </summary>
+ Log,
+
+ /// <summary>
+ /// The message should not be logged.
+ /// </summary>
+ Ignore,
+
+ /// <summary>
+ /// The message should be logged and processing should be finished.
+ /// </summary>
+ LogFinal,
+
+ /// <summary>
+ /// The message should not be logged and processing should be finished.
+ /// </summary>
+ IgnoreFinal,
+ }
+}
diff --git a/src/NLog/Filters/ConditionBasedFilter.cs b/src/NLog/Filters/ConditionBasedFilter.cs
new file mode 100644
index 0000000..328ef50
--- /dev/null
+++ b/src/NLog/Filters/ConditionBasedFilter.cs
@@ -0,0 +1,90 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+
+using NLog;
+using NLog.Config;
+using NLog.Conditions;
+
+namespace NLog.Filters
+{
+ /// <summary>
+ /// Matches when the specified condition is met.
+ /// </summary>
+ /// <remarks>
+ /// Conditions are expressed using a simple language
+ /// described <a href="conditions.html">here</a>.
+ /// </remarks>
+ [Filter("when")]
+ public class ConditionBasedFilter: Filter
+ {
+ private ConditionExpression _condition = null;
+
+ /// <summary>
+ /// Initializes a new instance of the filter object.
+ /// </summary>
+ public ConditionBasedFilter(){}
+
+ /// <summary>
+ /// The condition expression.
+ /// </summary>
+ public string Condition
+ {
+ get { return _condition.ToString(); }
+ set { _condition = ConditionParser.ParseExpression(value); }
+ }
+
+ /// <summary>
+ /// Checks whether log event should be logged or not.
+ /// </summary>
+ /// <param name="logEvent">Log event.</param>
+ /// <returns>
+ /// <see cref="FilterResult.Ignore"/> - if the log event should be ignored<br/>
+ /// <see cref="FilterResult.Neutral"/> - if the filter doesn't want to decide<br/>
+ /// <see cref="FilterResult.Log"/> - if the log event should be logged<br/>
+ /// </returns>
+ protected internal override FilterResult Check(LogEventInfo logEvent)
+ {
+ if (_condition == null)
+ return FilterResult.Neutral;
+
+ object val = _condition.Evaluate(logEvent);
+ if (val != null && val is bool && ((bool)val))
+ return Result;
+ else
+ return FilterResult.Neutral;
+ }
+ }
+}
diff --git a/src/NLog/Filters/LayoutBasedFilter.cs b/src/NLog/Filters/LayoutBasedFilter.cs
new file mode 100644
index 0000000..b1707fa
--- /dev/null
+++ b/src/NLog/Filters/LayoutBasedFilter.cs
@@ -0,0 +1,83 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+
+using NLog;
+using NLog.Config;
+
+namespace NLog.Filters
+{
+ /// <summary>
+ /// A base class for filters that are based on comparing a value to a layout.
+ /// </summary>
+ public abstract class LayoutBasedFilter: Filter
+ {
+ /// <summary>
+ /// Initializes a new instance of <see cref="LayoutBasedFilter"/>.
+ /// </summary>
+ protected LayoutBasedFilter(){}
+
+ private Layout _compiledlayout;
+
+ /// <summary>
+ /// The layout text;
+ /// </summary>
+ [RequiredParameter]
+ public string Layout
+ {
+ get { return _compiledlayout.Text; }
+ set { _compiledlayout = new Layout(value); }
+ }
+
+ /// <summary>
+ /// Compiled layout.
+ /// </summary>
+ protected Layout CompiledLayout
+ {
+ get { return _compiledlayout; }
+ }
+
+ /// <summary>
+ /// Determines whether stack trace information should be gathered
+ /// during log event processing. By default it calls <see cref="NLog.Layout.NeedsStackTrace" /> on
+ /// <see cref="TargetWithLayout.CompiledLayout" />.
+ /// </summary>
+ /// <returns>0 - don't include stack trace<br/>1 - include stack trace without source file information<br/>2 - include full stack trace</returns>
+ public override int NeedsStackTrace()
+ {
+ return CompiledLayout.NeedsStackTrace();
+ }
+ }
+}
diff --git a/src/NLog/Filters/WhenContains.cs b/src/NLog/Filters/WhenContains.cs
new file mode 100644
index 0000000..da6321b
--- /dev/null
+++ b/src/NLog/Filters/WhenContains.cs
@@ -0,0 +1,105 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+
+using NLog;
+using NLog.Config;
+
+namespace NLog.Filters
+{
+ /// <summary>
+ /// Matches when the calculated layout contains the specified substring.
+ /// This filter is deprecated in favour of <c><when /></c> which is based on <a href="conditions.html">contitions</a>
+ /// </summary>
+ [Filter("whenContains")]
+ public class WhenContainsFilter: LayoutBasedFilter
+ {
+ /// <summary>
+ /// Initializes a new instance of the filter object.
+ /// </summary>
+ public WhenContainsFilter(){}
+
+ private bool _ignoreCase = false;
+
+ /// <summary>
+ /// Ignore case when comparing strings.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool IgnoreCase
+ {
+ get { return _ignoreCase; }
+ set { _ignoreCase = value; }
+ }
+
+ private string _substring;
+
+ /// <summary>
+ /// Substring to be matched.
+ /// </summary>
+ [RequiredParameter]
+ public string Substring
+ {
+ get { return _substring; }
+ set { _substring = value; }
+ }
+
+ /// <summary>
+ /// Checks whether log event should be logged or not.
+ /// </summary>
+ /// <param name="logEvent">Log event.</param>
+ /// <returns>
+ /// <see cref="FilterResult.Ignore"/> - if the log event should be ignored<br/>
+ /// <see cref="FilterResult.Neutral"/> - if the filter doesn't want to decide<br/>
+ /// <see cref="FilterResult.Log"/> - if the log event should be logged<br/>
+ /// </returns>
+ protected internal override FilterResult Check(LogEventInfo logEvent)
+ {
+ if (IgnoreCase)
+ {
+ if (CompiledLayout.GetFormattedMessage(logEvent).ToLower().IndexOf(Substring.ToLower()) >= 0)
+ return Result;
+ else
+ return FilterResult.Neutral;
+ }
+ else
+ {
+ if (CompiledLayout.GetFormattedMessage(logEvent).IndexOf(Substring) >= 0)
+ return Result;
+ else
+ return FilterResult.Neutral;
+ }
+ }
+ }
+}
diff --git a/src/NLog/Filters/WhenEqual.cs b/src/NLog/Filters/WhenEqual.cs
new file mode 100644
index 0000000..6c7b26b
--- /dev/null
+++ b/src/NLog/Filters/WhenEqual.cs
@@ -0,0 +1,95 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+
+using NLog;
+using NLog.Config;
+
+namespace NLog.Filters
+{
+ /// <summary>
+ /// Matches when the calculated layout is equal to the specified substring.
+ /// This filter is deprecated in favour of <c><when /></c> which is based on <a href="conditions.html">contitions</a>
+ /// </summary>
+ [Filter("whenEqual")]
+ public class WhenEqualFilter: LayoutBasedFilter
+ {
+ /// <summary>
+ /// Initializes a new instance of the filter object.
+ /// </summary>
+ public WhenEqualFilter(){}
+
+ private bool _ignoreCase = false;
+
+ /// <summary>
+ /// Ignore case when comparing strings.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool IgnoreCase
+ {
+ get { return _ignoreCase; }
+ set { _ignoreCase = value; }
+ }
+
+ private string _compareTo;
+
+ /// <summary>
+ /// String to compare the layout to.
+ /// </summary>
+ [RequiredParameter]
+ public string CompareTo
+ {
+ get { return _compareTo; }
+ set { _compareTo = value; }
+ }
+
+ /// <summary>
+ /// Checks whether log event should be logged or not.
+ /// </summary>
+ /// <param name="logEvent">Log event.</param>
+ /// <returns>
+ /// <see cref="FilterResult.Ignore"/> - if the log event should be ignored<br/>
+ /// <see cref="FilterResult.Neutral"/> - if the filter doesn't want to decide<br/>
+ /// <see cref="FilterResult.Log"/> - if the log event should be logged<br/>
+ /// </returns>
+ protected internal override FilterResult Check(LogEventInfo logEvent)
+ {
+ if (0 == String.Compare(CompiledLayout.GetFormattedMessage(logEvent), CompareTo, IgnoreCase))
+ return Result;
+ else
+ return FilterResult.Neutral;
+ }
+ }
+}
diff --git a/src/NLog/Filters/WhenNotContains.cs b/src/NLog/Filters/WhenNotContains.cs
new file mode 100644
index 0000000..4324584
--- /dev/null
+++ b/src/NLog/Filters/WhenNotContains.cs
@@ -0,0 +1,107 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+
+using NLog;
+using NLog.Config;
+
+namespace NLog.Filters
+{
+ /// <summary>
+ /// Matches when the calculated layout does NOT contain the specified substring.
+ /// This filter is deprecated in favour of <c><when /></c> which is based on <a href="conditions.html">contitions</a>
+ /// </summary>
+ [Filter("whenNotContains")]
+ public class WhenNotContainsFilter: LayoutBasedFilter
+ {
+ /// <summary>
+ /// Initializes a new instance of the filter object.
+ /// </summary>
+ public WhenNotContainsFilter()
+ {
+ }
+
+ private string _substring;
+
+ /// <summary>
+ /// Substring to be matched.
+ /// </summary>
+ [RequiredParameter]
+ public string Substring
+ {
+ get { return _substring; }
+ set { _substring = value; }
+ }
+
+ private bool _ignoreCase = false;
+
+ /// <summary>
+ /// Ignore case when comparing strings.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool IgnoreCase
+ {
+ get { return _ignoreCase; }
+ set { _ignoreCase = value; }
+ }
+
+ /// <summary>
+ /// Checks whether log event should be logged or not.
+ /// </summary>
+ /// <param name="logEvent">Log event.</param>
+ /// <returns>
+ /// <see cref="FilterResult.Ignore"/> - if the log event should be ignored<br/>
+ /// <see cref="FilterResult.Neutral"/> - if the filter doesn't want to decide<br/>
+ /// <see cref="FilterResult.Log"/> - if the log event should be logged<br/>
+ /// </returns>
+ protected internal override FilterResult Check(LogEventInfo logEvent)
+ {
+ if (IgnoreCase)
+ {
+ if (CompiledLayout.GetFormattedMessage(logEvent).ToLower().IndexOf(Substring.ToLower()) < 0)
+ return Result;
+ else
+ return FilterResult.Neutral;
+ }
+ else
+ {
+ if (CompiledLayout.GetFormattedMessage(logEvent).IndexOf(Substring) < 0)
+ return Result;
+ else
+ return FilterResult.Neutral;
+ }
+ }
+ }
+}
diff --git a/src/NLog/Filters/WhenNotEqual.cs b/src/NLog/Filters/WhenNotEqual.cs
new file mode 100644
index 0000000..8643fa3
--- /dev/null
+++ b/src/NLog/Filters/WhenNotEqual.cs
@@ -0,0 +1,95 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+
+using NLog;
+using NLog.Config;
+
+namespace NLog.Filters
+{
+ /// <summary>
+ /// Matches when the calculated layout is NOT equal to the specified substring.
+ /// This filter is deprecated in favour of <c><when /></c> which is based on <a href="conditions.html">contitions</a>
+ /// </summary>
+ [Filter("whenNotEqual")]
+ public class WhenNotEqualFilter: LayoutBasedFilter
+ {
+ /// <summary>
+ /// Initializes a new instance of the filter object.
+ /// </summary>
+ public WhenNotEqualFilter(){}
+
+ private string _compareTo;
+
+ /// <summary>
+ /// String to compare the layout to.
+ /// </summary>
+ [RequiredParameter]
+ public string CompareTo
+ {
+ get { return _compareTo; }
+ set { _compareTo = value; }
+ }
+
+ private bool _ignoreCase = false;
+
+ /// <summary>
+ /// Ignore case when comparing strings.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool IgnoreCase
+ {
+ get { return _ignoreCase; }
+ set { _ignoreCase = value; }
+ }
+
+ /// <summary>
+ /// Checks whether log event should be logged or not.
+ /// </summary>
+ /// <param name="logEvent">Log event.</param>
+ /// <returns>
+ /// <see cref="FilterResult.Ignore"/> - if the log event should be ignored<br/>
+ /// <see cref="FilterResult.Neutral"/> - if the filter doesn't want to decide<br/>
+ /// <see cref="FilterResult.Log"/> - if the log event should be logged<br/>
+ /// </returns>
+ protected internal override FilterResult Check(LogEventInfo logEvent)
+ {
+ if (0 != String.Compare(CompiledLayout.GetFormattedMessage(logEvent), CompareTo, IgnoreCase))
+ return Result;
+ else
+ return FilterResult.Neutral;
+ }
+ }
+}
diff --git a/src/NLog/GDC.cs b/src/NLog/GDC.cs
new file mode 100644
index 0000000..3ac2296
--- /dev/null
+++ b/src/NLog/GDC.cs
@@ -0,0 +1,99 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+
+namespace NLog
+{
+ /// <summary>
+ /// Global Diagnostics Context - a dictionary structure to hold per-application-instance values.
+ /// </summary>
+ public sealed class GDC
+ {
+ private static IDictionary _dict = new Hashtable();
+
+ private GDC(){}
+
+ /// <summary>
+ /// Sets the Global Diagnostics Context item to the specified value.
+ /// </summary>
+ /// <param name="item">Item name.</param>
+ /// <param name="value">Item value.</param>
+ public static void Set(string item, string value)
+ {
+ _dict[item] = value;
+ }
+
+ /// <summary>
+ /// Gets the Global Diagnostics Context named item.
+ /// </summary>
+ /// <param name="item">Item name.</param>
+ /// <returns>The item value of String.Empty if the value is not present.</returns>
+ public static string Get(string item)
+ {
+ string s = (string)_dict[item];
+ if (s == null)
+ return String.Empty;
+ else
+ return s;
+ }
+
+ /// <summary>
+ /// Checks whether the specified item exists in the Global Diagnostics Context.
+ /// </summary>
+ /// <param name="item">Item name.</param>
+ /// <returns>A boolean indicating whether the specified item exists in current thread GDC.</returns>
+ public static bool Contains(string item)
+ {
+ return _dict.Contains(item);
+ }
+
+ /// <summary>
+ /// Removes the specified item from the Global Diagnostics Context.
+ /// </summary>
+ /// <param name="item">Item name.</param>
+ public static void Remove(string item)
+ {
+ _dict.Remove(item);
+ }
+
+ /// <summary>
+ /// Clears the content of the GDC.
+ /// </summary>
+ public static void Clear()
+ {
+ _dict.Clear();
+ }
+ }
+}
diff --git a/src/NLog/ILayout.cs b/src/NLog/ILayout.cs
new file mode 100644
index 0000000..c492f28
--- /dev/null
+++ b/src/NLog/ILayout.cs
@@ -0,0 +1,104 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+
+using NLog.Internal;
+using NLog.LayoutRenderers;
+
+using System.Threading;
+
+namespace NLog
+{
+ /// <summary>
+ /// Abstract interface that layouts must implement.
+ /// </summary>
+ public interface ILayout
+ {
+ /// <summary>
+ /// Renders the layout for the specified logging event by invoking layout renderers.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ /// <returns>The rendered layout.</returns>
+ string GetFormattedMessage(LogEventInfo logEvent);
+
+ /// <summary>
+ /// Returns the value indicating whether a stack trace and/or the source file
+ /// information should be gathered during layout processing.
+ /// </summary>
+ /// <returns>0 - don't include stack trace<br/>1 - include stack trace without source file information<br/>2 - include full stack trace</returns>
+ int NeedsStackTrace();
+
+ /// <summary>
+ /// Returns the value indicating whether this layout includes any volatile
+ /// layout renderers.
+ /// </summary>
+ /// <returns><see langword="true" /> when the layout includes at least
+ /// one volatile renderer, <see langword="false"/> otherwise.</returns>
+ /// <remarks>
+ /// Volatile layout renderers are dependent on information not contained
+ /// in <see cref="LogEventInfo"/> (such as thread-specific data, MDC data, NDC data).
+ /// </remarks>
+ bool IsVolatile();
+
+ /// <summary>
+ /// Precalculates the layout for the specified log event and stores the result
+ /// in per-log event cache.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ /// <remarks>
+ /// Calling this method enables you to store the log event in a buffer
+ /// and/or potentially evaluate it in another thread even though the
+ /// layout may contain thread-dependent renderer.
+ /// </remarks>
+ void Precalculate(LogEventInfo logEvent);
+
+ /// <summary>
+ /// Initializes the layout.
+ /// </summary>
+ void Initialize();
+
+ /// <summary>
+ /// Closes the layout.
+ /// </summary>
+ void Close();
+
+ /// <summary>
+ /// Add this layout and all sub-layouts to the specified collection..
+ /// </summary>
+ /// <param name="layouts">The collection of layouts.</param>
+ void PopulateLayouts(LayoutCollection layouts);
+ }
+}
diff --git a/src/NLog/ILayoutWithHeaderAndFooter.cs b/src/NLog/ILayoutWithHeaderAndFooter.cs
new file mode 100644
index 0000000..8d630bd
--- /dev/null
+++ b/src/NLog/ILayoutWithHeaderAndFooter.cs
@@ -0,0 +1,65 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+
+using NLog.Internal;
+using NLog.LayoutRenderers;
+
+using System.Threading;
+
+namespace NLog
+{
+ /// <summary>
+ /// Layout with header and footer.
+ /// </summary>
+ public interface ILayoutWithHeaderAndFooter
+ {
+ /// <summary>
+ /// Main layout (can be repeated multiple times)
+ /// </summary>
+ ILayout Layout { get; set; }
+
+ /// <summary>
+ /// Header
+ /// </summary>
+ ILayout Header { get; set; }
+
+ /// <summary>
+ /// Footer
+ /// </summary>
+ ILayout Footer { get; set; }
+ }
+}
diff --git a/src/NLog/Internal/CompactFrameworkHelper.cs b/src/NLog/Internal/CompactFrameworkHelper.cs
new file mode 100644
index 0000000..8111565
--- /dev/null
+++ b/src/NLog/Internal/CompactFrameworkHelper.cs
@@ -0,0 +1,88 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if NETCF
+
+using System;
+using System.IO;
+using System.Text;
+using System.Runtime.InteropServices;
+
+namespace NLog.Internal
+{
+ internal sealed class CompactFrameworkHelper
+ {
+ private static string _exeName;
+ private static string _exeBaseDir;
+
+ public static string GetExeFileName()
+ {
+ if (_exeName == null)
+ {
+ LoadExeInfo();
+ }
+ return _exeName;
+ }
+
+ public static string GetExeBaseDir()
+ {
+ if (_exeName == null)
+ {
+ LoadExeInfo();
+ }
+ return _exeBaseDir;
+ }
+
+ private static void LoadExeInfo()
+ {
+ lock (typeof(CompactFrameworkHelper))
+ {
+ if (_exeName == null)
+ {
+ StringBuilder sb = new StringBuilder(512);
+
+ // passing 0 as the first parameter gets us the name of the EXE
+
+ GetModuleFileName(IntPtr.Zero, sb, sb.Capacity);
+ _exeName = sb.ToString();
+ _exeBaseDir = Path.GetDirectoryName(_exeName);
+ }
+ }
+ }
+
+ [DllImport("coredll.dll", CharSet=CharSet.Unicode)]
+ private static extern int GetModuleFileName(IntPtr hModule, StringBuilder szBuffer, int nCapacity);
+ }
+}
+
+#endif
diff --git a/src/NLog/Internal/CurrentTimeGetter.cs b/src/NLog/Internal/CurrentTimeGetter.cs
new file mode 100644
index 0000000..a0fd103
--- /dev/null
+++ b/src/NLog/Internal/CurrentTimeGetter.cs
@@ -0,0 +1,89 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Reflection;
+using System.Collections;
+
+using NLog.Config;
+using NLog.Internal;
+using System.Runtime.InteropServices;
+
+namespace NLog
+{
+ internal class CurrentTimeGetter
+ {
+ delegate DateTime GetDelegate();
+
+ private static GetDelegate _getDelegate;
+
+ static CurrentTimeGetter()
+ {
+ // this is to keep Mono compiler quiet
+ _getDelegate = new GetDelegate(NonOptimizedGet);
+ _getDelegate = new GetDelegate(ThrottledGet);
+ }
+
+ public static DateTime Now
+ {
+ get { return _getDelegate(); }
+ }
+
+ private static int _lastTicks = -1;
+ private static DateTime _lastDateTime = DateTime.MinValue;
+
+ static DateTime NonOptimizedGet()
+ {
+ return DateTime.Now;
+ }
+
+ static DateTime ThrottledGet()
+ {
+ int t = Environment.TickCount;
+
+ if (t != _lastTicks)
+ {
+ DateTime dt = DateTime.Now;
+
+ _lastTicks = t;
+ _lastDateTime = dt;
+ return dt;
+ }
+ else
+ {
+ return _lastDateTime;
+ }
+ }
+ }
+}
diff --git a/src/NLog/Internal/DictionaryBase.cs b/src/NLog/Internal/DictionaryBase.cs
new file mode 100644
index 0000000..7248b26
--- /dev/null
+++ b/src/NLog/Internal/DictionaryBase.cs
@@ -0,0 +1,62 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if NETCF
+
+// a substitute for the missing .NET CF Class
+// implements minimal wrapper around a Hashtable - only the needed
+// member functions are implemented
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace System.Collections
+{
+ internal class DictionaryBase
+ {
+ private Hashtable _hashtable = new Hashtable();
+
+ public IDictionary Dictionary
+ {
+ get { return _hashtable; }
+ }
+
+ public void Clear()
+ {
+ _hashtable.Clear();
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Internal/EnvironmentHelper.cs b/src/NLog/Internal/EnvironmentHelper.cs
new file mode 100644
index 0000000..f32f60e
--- /dev/null
+++ b/src/NLog/Internal/EnvironmentHelper.cs
@@ -0,0 +1,61 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+using System;
+using System.Security;
+
+namespace NLog.Internal
+{
+ internal sealed class EnvironmentHelper
+ {
+ private EnvironmentHelper(){}
+
+ public static string GetSafeEnvironmentVariable(string name)
+ {
+ try
+ {
+ string s = Environment.GetEnvironmentVariable(name);
+ if (s == "")
+ return null;
+ else
+ return s;
+ }
+ catch (SecurityException)
+ {
+ return "";
+ }
+ }
+ }
+}
+#endif
diff --git a/src/NLog/Internal/ExtensionUtils.cs b/src/NLog/Internal/ExtensionUtils.cs
new file mode 100644
index 0000000..6826b37
--- /dev/null
+++ b/src/NLog/Internal/ExtensionUtils.cs
@@ -0,0 +1,66 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Reflection;
+using System.Collections;
+
+using NLog.Config;
+using NLog.Internal;
+
+namespace NLog
+{
+ /// <summary>
+ /// A class that loads and manages NLog extension assemblies.
+ /// </summary>
+ public class ExtensionUtils
+ {
+ private static ArrayList _extensionAssemblies = new ArrayList();
+
+ static ExtensionUtils()
+ {
+ // load default targets, filters and layout renderers.
+ _extensionAssemblies.Add(typeof(NLog.LogManager).Assembly);
+ }
+
+ /// <summary>
+ /// Gets the list of loaded NLog extension assemblies.
+ /// </summary>
+ /// <returns>An <see cref="ArrayList"/> containing all NLog extension assemblies that have been loaded.</returns>
+ public static ArrayList GetExtensionAssemblies()
+ {
+ return _extensionAssemblies;
+ }
+ }
+}
diff --git a/src/NLog/Internal/FactoryHelper.cs b/src/NLog/Internal/FactoryHelper.cs
new file mode 100644
index 0000000..c33d122
--- /dev/null
+++ b/src/NLog/Internal/FactoryHelper.cs
@@ -0,0 +1,59 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Reflection;
+using System.Globalization;
+using NLog.Internal;
+
+namespace NLog.Internal
+{
+ internal class FactoryHelper
+ {
+ private static Type[]EmptyTypes = new Type[0];
+ private static object[]EmptyParams = new object[0];
+
+ public static object CreateInstance(Type t)
+ {
+ ConstructorInfo constructor = t.GetConstructor(EmptyTypes); //t.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null);
+ if (constructor != null)
+ {
+ return constructor.Invoke(EmptyParams);
+ }
+ else
+ {
+ throw new Exception("Cannot access the constructor of type: " + t.FullName + ". Is the required permission granted?");
+ }
+ }
+ }
+}
diff --git a/src/NLog/Internal/FileAppenders/BaseFileAppender.cs b/src/NLog/Internal/FileAppenders/BaseFileAppender.cs
new file mode 100644
index 0000000..592bb3a
--- /dev/null
+++ b/src/NLog/Internal/FileAppenders/BaseFileAppender.cs
@@ -0,0 +1,206 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Threading;
+using System.Collections;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Config;
+
+using NLog.Internal;
+using System.Runtime.InteropServices;
+#if !NETCF
+using NLog.Internal.Win32;
+#endif
+
+namespace NLog.Internal.FileAppenders
+{
+ internal abstract class BaseFileAppender
+ {
+ private Random _random = new Random();
+ private string _fileName;
+ private ICreateFileParameters _createParameters;
+ private DateTime _openTime;
+ private DateTime _lastWriteTime;
+
+ public string FileName
+ {
+ get { return _fileName; }
+ }
+
+ public DateTime LastWriteTime
+ {
+ get { return _lastWriteTime; }
+ }
+
+ public DateTime OpenTime
+ {
+ get { return _openTime; }
+ }
+
+ public ICreateFileParameters CreateFileParameters
+ {
+ get { return _createParameters; }
+ }
+
+ protected void FileTouched()
+ {
+ _lastWriteTime = CurrentTimeGetter.Now;
+ }
+
+ protected void FileTouched(DateTime dt)
+ {
+ _lastWriteTime = dt;
+ }
+
+ public BaseFileAppender(string fileName, ICreateFileParameters createParameters)
+ {
+ _fileName = fileName;
+ _createParameters = createParameters;
+ _openTime = CurrentTimeGetter.Now;
+ _lastWriteTime = DateTime.MinValue;
+ }
+
+ public abstract void Write(byte[] bytes);
+
+ public abstract void Flush();
+ public abstract void Close();
+
+ public abstract bool GetFileInfo(out DateTime lastWriteTime, out long fileLength);
+
+ protected FileStream CreateFileStream(bool allowConcurrentWrite)
+ {
+ int currentDelay = _createParameters.ConcurrentWriteAttemptDelay;
+
+ InternalLogger.Trace("Opening {0} with concurrentWrite={1}", FileName, allowConcurrentWrite);
+ for (int i = 0; i < _createParameters.ConcurrentWriteAttempts; ++i)
+ {
+ try
+ {
+ try
+ {
+ return TryCreateFileStream(allowConcurrentWrite);
+ }
+ catch (DirectoryNotFoundException)
+ {
+ if (!_createParameters.CreateDirs)
+ throw;
+
+ Directory.CreateDirectory(Path.GetDirectoryName(FileName));
+ return TryCreateFileStream(allowConcurrentWrite);
+ }
+ }
+ catch (IOException)
+ {
+ if (!_createParameters.ConcurrentWrites || !allowConcurrentWrite || i + 1 == _createParameters.ConcurrentWriteAttempts)
+ throw; // rethrow
+
+ int actualDelay = _random.Next(currentDelay);
+ InternalLogger.Warn("Attempt #{0} to open {1} failed. Sleeping for {2}ms", i, FileName, actualDelay);
+ currentDelay *= 2;
+ System.Threading.Thread.Sleep(actualDelay);
+ }
+ }
+ throw new Exception("Should not be reached.");
+ }
+
+
+#if !NETCF
+ private FileStream WindowsCreateFile(string fileName, bool allowConcurrentWrite)
+ {
+ int fileShare = Win32FileHelper.FILE_SHARE_READ;
+
+ if (allowConcurrentWrite)
+ fileShare |= Win32FileHelper.FILE_SHARE_WRITE;
+
+ if (_createParameters.EnableFileDelete && PlatformDetector.GetCurrentRuntimeOS() != RuntimeOS.Windows)
+ fileShare |= Win32FileHelper.FILE_SHARE_DELETE;
+
+ IntPtr hFile = Win32FileHelper.CreateFile(
+ fileName,
+ Win32FileHelper.FileAccess.GenericWrite,
+ fileShare,
+ IntPtr.Zero,
+ Win32FileHelper.CreationDisposition.OpenAlways,
+ _createParameters.FileAttributes, IntPtr.Zero);
+
+ if (hFile.ToInt32() == -1)
+ Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
+
+ FileStream returnValue;
+
+#if DOTNET_2_0 || NETCF_2_0
+ Microsoft.Win32.SafeHandles.SafeFileHandle safeHandle = new Microsoft.Win32.SafeHandles.SafeFileHandle(hFile, true);
+ returnValue = new FileStream(safeHandle, FileAccess.Write, _createParameters.BufferSize);
+#else
+ returnValue = new FileStream(hFile, FileAccess.Write, true, _createParameters.BufferSize);
+#endif
+ returnValue.Seek(0, SeekOrigin.End);
+ return returnValue;
+ }
+#endif
+
+ private FileStream TryCreateFileStream(bool allowConcurrentWrite)
+ {
+ FileShare fileShare = FileShare.Read;
+
+ if (allowConcurrentWrite)
+ fileShare = FileShare.ReadWrite;
+
+#if DOTNET_2_0
+ if (_createParameters.EnableFileDelete && PlatformDetector.GetCurrentRuntimeOS() != RuntimeOS.Windows)
+ {
+ fileShare |= FileShare.Delete;
+ }
+#endif
+
+#if !NETCF
+ if (PlatformDetector.IsCurrentOSCompatibleWith(RuntimeOS.WindowsNT) ||
+ PlatformDetector.IsCurrentOSCompatibleWith(RuntimeOS.Windows))
+ {
+ return WindowsCreateFile(FileName, allowConcurrentWrite);
+ }
+#endif
+
+ return new FileStream(FileName,
+ FileMode.Append,
+ FileAccess.Write,
+ fileShare,
+ _createParameters.BufferSize);
+ }
+ }
+}
diff --git a/src/NLog/Internal/FileAppenders/CountingSingleProcessFileAppender.cs b/src/NLog/Internal/FileAppenders/CountingSingleProcessFileAppender.cs
new file mode 100644
index 0000000..22d6b97
--- /dev/null
+++ b/src/NLog/Internal/FileAppenders/CountingSingleProcessFileAppender.cs
@@ -0,0 +1,113 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Threading;
+using System.Collections;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Config;
+
+using NLog.Internal;
+
+namespace NLog.Internal.FileAppenders
+{
+ internal class CountingSingleProcessFileAppender : BaseFileAppender
+ {
+ private FileStream _file;
+ private long _fileLength;
+
+ public static readonly IFileAppenderFactory TheFactory = new Factory();
+
+ class Factory : IFileAppenderFactory
+ {
+ public BaseFileAppender Open(string fileName, ICreateFileParameters parameters)
+ {
+ return new CountingSingleProcessFileAppender(fileName, parameters);
+ }
+ }
+
+ public CountingSingleProcessFileAppender(string fileName, ICreateFileParameters parameters) : base(fileName, parameters)
+ {
+ FileInfo fi = new FileInfo(fileName);
+ if (fi.Exists)
+ {
+ FileTouched(fi.LastWriteTime);
+ _fileLength = fi.Length;
+ }
+ else
+ {
+ FileTouched();
+ _fileLength = 0;
+ }
+
+ _file = CreateFileStream(false);
+ }
+
+ public override void Write(byte[] bytes)
+ {
+ if (_file == null)
+ return;
+ _fileLength += bytes.Length;
+ _file.Write(bytes, 0, bytes.Length);
+ FileTouched();
+ }
+
+ public override void Flush()
+ {
+ if (_file == null)
+ return;
+ _file.Flush();
+ FileTouched();
+ }
+
+ public override void Close()
+ {
+ if (_file == null)
+ return;
+ //InternalLogger.Trace("Closing '{0}'", _fileName);
+ _file.Close();
+ _file = null;
+ }
+
+ public override bool GetFileInfo(out DateTime lastWriteTime, out long fileLength)
+ {
+ lastWriteTime = LastWriteTime;
+ fileLength = _fileLength;
+ return true;
+ }
+ }
+}
diff --git a/src/NLog/Internal/FileAppenders/ICreateFile.cs b/src/NLog/Internal/FileAppenders/ICreateFile.cs
new file mode 100644
index 0000000..6c8dcde
--- /dev/null
+++ b/src/NLog/Internal/FileAppenders/ICreateFile.cs
@@ -0,0 +1,66 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Threading;
+using System.Collections;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Config;
+
+using NLog.Internal;
+#if !NETCF
+using NLog.Internal.Win32;
+#endif
+
+namespace NLog.Internal.FileAppenders
+{
+ /// <summary>
+ /// Interface that provides parameters for create file function.
+ /// </summary>
+ internal interface ICreateFileParameters
+ {
+ int ConcurrentWriteAttemptDelay { get; }
+ int ConcurrentWriteAttempts { get; }
+ bool ConcurrentWrites { get; }
+ bool CreateDirs { get; }
+ bool EnableFileDelete { get; }
+ int BufferSize { get; }
+#if !NETCF
+ Win32FileAttributes FileAttributes { get; }
+#endif
+ }
+}
diff --git a/src/NLog/Internal/FileAppenders/IFileAppenderFactory.cs b/src/NLog/Internal/FileAppenders/IFileAppenderFactory.cs
new file mode 100644
index 0000000..ca297be
--- /dev/null
+++ b/src/NLog/Internal/FileAppenders/IFileAppenderFactory.cs
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Threading;
+using System.Collections;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Config;
+
+using NLog.Internal;
+
+namespace NLog.Internal.FileAppenders
+{
+ internal interface IFileAppenderFactory
+ {
+ BaseFileAppender Open(string fileName, ICreateFileParameters parameters);
+ }
+}
\ No newline at end of file
diff --git a/src/NLog/Internal/FileAppenders/MutexMultiProcessFileAppender.cs b/src/NLog/Internal/FileAppenders/MutexMultiProcessFileAppender.cs
new file mode 100644
index 0000000..23ea1f5
--- /dev/null
+++ b/src/NLog/Internal/FileAppenders/MutexMultiProcessFileAppender.cs
@@ -0,0 +1,161 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Threading;
+using System.Text;
+using System.Collections;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Config;
+
+using NLog.Internal;
+
+namespace NLog.Internal.FileAppenders
+{
+ /// <summary>
+ /// Provides a multiprocess-safe atomic file appends while
+ /// keeping the files open.
+ /// </summary>
+ /// <remarks>
+ /// On Unix you can get all the appends to be atomic, even when multiple
+ /// processes are trying to write to the same file, because setting the file
+ /// pointer to the end of the file and appending can be made one operation.
+ /// On Win32 we need to maintain some synchronization between processes
+ /// (global named mutex is used for this)
+ /// </remarks>
+ internal class MutexMultiProcessFileAppender : BaseFileAppender
+ {
+ private Mutex _mutex;
+ private FileStream _file;
+
+ public static readonly IFileAppenderFactory TheFactory = new Factory();
+
+ public class Factory : IFileAppenderFactory
+ {
+ public BaseFileAppender Open(string fileName, ICreateFileParameters parameters)
+ {
+ return new MutexMultiProcessFileAppender(fileName, parameters);
+ }
+ }
+
+ public MutexMultiProcessFileAppender(string fileName, ICreateFileParameters parameters) : base(fileName, parameters)
+ {
+ try
+ {
+ _mutex = new Mutex(false, GetMutexName(fileName));
+ _file = CreateFileStream(true);
+ }
+ catch
+ {
+ if (_mutex != null)
+ {
+ _mutex.Close();
+ _mutex = null;
+ }
+ if (_file != null)
+ {
+ _file.Close();
+ _file = null;
+ }
+ throw;
+ }
+ }
+
+ public override void Write(byte[] bytes)
+ {
+ if (_mutex == null)
+ return;
+ _mutex.WaitOne();
+ try
+ {
+ _file.Seek(0, SeekOrigin.End);
+ _file.Write(bytes, 0, bytes.Length);
+ _file.Flush();
+ FileTouched();
+ }
+ finally
+ {
+ _mutex.ReleaseMutex();
+ }
+ }
+
+ public override void Close()
+ {
+ InternalLogger.Trace("Closing '{0}'", FileName);
+ if (_mutex != null)
+ {
+ _mutex.Close();
+ }
+ if (_file != null)
+ {
+ _file.Close();
+ }
+ _mutex = null;
+ _file = null;
+ FileTouched();
+ }
+
+ public override void Flush()
+ {
+ // do nothing, the stream is always flushed
+ }
+
+ private string GetMutexName(string fileName)
+ {
+ string canonicalName = Path.GetFullPath(fileName).ToLower();
+
+ canonicalName = canonicalName.Replace('\\', '_');
+ canonicalName = canonicalName.Replace('/', '_');
+ canonicalName = canonicalName.Replace(':', '_');
+
+ return "filelock-mutex-" + canonicalName;
+ }
+
+ public override bool GetFileInfo(out DateTime lastWriteTime, out long fileLength)
+ {
+#if NET_2_API
+ return FileInfoHelper.Helper.GetFileInfo(FileName, _file.SafeFileHandle.DangerousGetHandle(), out lastWriteTime, out fileLength);
+#else
+ return FileInfoHelper.Helper.GetFileInfo(FileName, _file.Handle, out lastWriteTime, out fileLength);
+#endif
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Internal/FileAppenders/RetryingMultiProcessFileAppender.cs b/src/NLog/Internal/FileAppenders/RetryingMultiProcessFileAppender.cs
new file mode 100644
index 0000000..20abc40
--- /dev/null
+++ b/src/NLog/Internal/FileAppenders/RetryingMultiProcessFileAppender.cs
@@ -0,0 +1,100 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Threading;
+using System.Collections;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Config;
+
+using NLog.Internal;
+
+namespace NLog.Internal.FileAppenders
+{
+ internal class RetryingMultiProcessFileAppender : BaseFileAppender
+ {
+ public static readonly IFileAppenderFactory TheFactory = new Factory();
+
+ public class Factory : IFileAppenderFactory
+ {
+ public BaseFileAppender Open(string fileName, ICreateFileParameters parameters)
+ {
+ return new RetryingMultiProcessFileAppender(fileName, parameters);
+ }
+ }
+
+ public RetryingMultiProcessFileAppender(string fileName, ICreateFileParameters parameters) : base(fileName, parameters)
+ {
+ }
+
+ public override void Write(byte[] bytes)
+ {
+ using (FileStream fileStream = CreateFileStream(false))
+ {
+ fileStream.Write(bytes, 0, bytes.Length);
+ }
+ FileTouched();
+ }
+
+ public override void Flush()
+ {
+ // nothing to do
+ }
+
+ public override void Close()
+ {
+ // nothing to do
+ }
+
+ public override bool GetFileInfo(out DateTime lastWriteTime, out long fileLength)
+ {
+ FileInfo fi = new FileInfo(FileName);
+ if (fi.Exists)
+ {
+ fileLength = fi.Length;
+ lastWriteTime = fi.LastWriteTime;
+ return true;
+ }
+ else
+ {
+ fileLength = -1;
+ lastWriteTime = DateTime.MinValue;
+ return false;
+ }
+ }
+ }
+}
diff --git a/src/NLog/Internal/FileAppenders/SingleProcessFileAppender.cs b/src/NLog/Internal/FileAppenders/SingleProcessFileAppender.cs
new file mode 100644
index 0000000..825f6d5
--- /dev/null
+++ b/src/NLog/Internal/FileAppenders/SingleProcessFileAppender.cs
@@ -0,0 +1,97 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Threading;
+using System.Collections;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Config;
+
+using NLog.Internal;
+
+namespace NLog.Internal.FileAppenders
+{
+ internal class SingleProcessFileAppender : BaseFileAppender
+ {
+ private FileStream _file;
+
+ public static readonly IFileAppenderFactory TheFactory = new Factory();
+
+ class Factory : IFileAppenderFactory
+ {
+ public BaseFileAppender Open(string fileName, ICreateFileParameters parameters)
+ {
+ return new SingleProcessFileAppender(fileName, parameters);
+ }
+ }
+
+ public SingleProcessFileAppender(string fileName, ICreateFileParameters parameters) : base(fileName, parameters)
+ {
+ _file = CreateFileStream(false);
+ }
+
+ public override void Write(byte[] bytes)
+ {
+ if (_file == null)
+ return;
+ _file.Write(bytes, 0, bytes.Length);
+ FileTouched();
+ }
+
+ public override void Flush()
+ {
+ if (_file == null)
+ return;
+ _file.Flush();
+ FileTouched();
+ }
+
+ public override void Close()
+ {
+ if (_file == null)
+ return;
+ InternalLogger.Trace("Closing '{0}'", FileName);
+ _file.Close();
+ _file = null;
+ }
+
+ public override bool GetFileInfo(out DateTime lastWriteTime, out long fileLength)
+ {
+ throw new NotSupportedException("SimpleProcessFileAppender doesn't support GetFileInfo");
+ }
+ }
+}
diff --git a/src/NLog/Internal/FileAppenders/UnixMultiProcessFileAppender.cs b/src/NLog/Internal/FileAppenders/UnixMultiProcessFileAppender.cs
new file mode 100644
index 0000000..fb6f4e2
--- /dev/null
+++ b/src/NLog/Internal/FileAppenders/UnixMultiProcessFileAppender.cs
@@ -0,0 +1,147 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if MONO
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Threading;
+using System.Text;
+using System.Collections;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Config;
+
+using NLog.Internal;
+
+using Mono.Unix;
+using Mono.Unix.Native;
+
+namespace NLog.Internal.FileAppenders
+{
+ /// <summary>
+ /// Provides a multiprocess-safe atomic file appends while
+ /// keeping the files open.
+ /// </summary>
+ /// <remarks>
+ /// On Unix you can get all the appends to be atomic, even when multiple
+ /// processes are trying to write to the same file, because setting the file
+ /// pointer to the end of the file and appending can be made one operation.
+ /// </remarks>
+ internal class UnixMultiProcessFileAppender : BaseFileAppender
+ {
+ private UnixStream _file;
+
+ public static readonly IFileAppenderFactory TheFactory = new Factory();
+
+ public class Factory : IFileAppenderFactory
+ {
+ public BaseFileAppender Open(string fileName, ICreateFileParameters parameters)
+ {
+ return new UnixMultiProcessFileAppender(fileName, parameters);
+ }
+ }
+
+ public UnixMultiProcessFileAppender(string fileName, ICreateFileParameters parameters) : base(fileName, parameters)
+ {
+ int fd = Syscall.open(fileName, OpenFlags.O_CREAT | OpenFlags.O_WRONLY | OpenFlags.O_APPEND, (FilePermissions)(6 | (6 << 3) | (6 << 6)));
+ if (fd == -1)
+ {
+ if (Stdlib.GetLastError() == Errno.ENOENT && parameters.CreateDirs)
+ {
+ string dirName = Path.GetDirectoryName(fileName);
+ if (!Directory.Exists(dirName) && parameters.CreateDirs)
+ Directory.CreateDirectory(dirName);
+
+ fd = Syscall.open(fileName, OpenFlags.O_CREAT | OpenFlags.O_WRONLY | OpenFlags.O_APPEND, (FilePermissions)(6 | (6 << 3) | (6 << 6)));
+ }
+ }
+ if (fd == -1)
+ UnixMarshal.ThrowExceptionForLastError();
+
+ try
+ {
+ _file = new UnixStream(fd, true);
+ }
+ catch
+ {
+ Syscall.close(fd);
+ throw;
+ }
+ }
+
+ public override void Write(byte[] bytes)
+ {
+ if (_file == null)
+ return;
+ _file.Write(bytes, 0, bytes.Length);
+ FileTouched();
+ }
+
+ public override void Close()
+ {
+ if (_file == null)
+ return;
+ InternalLogger.Trace("Closing '{0}'", FileName);
+ _file.Close();
+ _file = null;
+ FileTouched();
+ }
+
+ public override void Flush()
+ {
+ // do nothing, the stream is always flushed
+ }
+
+ public override bool GetFileInfo(out DateTime lastWriteTime, out long fileLength)
+ {
+ FileInfo fi = new FileInfo(FileName);
+ if (fi.Exists)
+ {
+ fileLength = fi.Length;
+ lastWriteTime = fi.LastWriteTime;
+ return true;
+ }
+ else
+ {
+ fileLength = -1;
+ lastWriteTime = DateTime.MinValue;
+ return false;
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Internal/FileInfoHelper.cs b/src/NLog/Internal/FileInfoHelper.cs
new file mode 100644
index 0000000..ab04a61
--- /dev/null
+++ b/src/NLog/Internal/FileInfoHelper.cs
@@ -0,0 +1,116 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Reflection;
+using System.Collections;
+
+using NLog.Config;
+using NLog.Internal;
+#if !NETCF
+using NLog.Internal.Win32;
+#endif
+using System.IO;
+
+namespace NLog.Internal
+{
+ // optimized routines to get the size and last write time
+ // of the specified file
+ internal abstract class FileInfoHelper
+ {
+ public static readonly FileInfoHelper Helper;
+
+ static FileInfoHelper()
+ {
+#if NETCF
+ Helper = new GenericFileInfoHelper();
+#else
+ if (PlatformDetector.IsCurrentOSCompatibleWith(RuntimeOS.Windows) ||
+ PlatformDetector.IsCurrentOSCompatibleWith(RuntimeOS.WindowsNT))
+ {
+ Helper = new Win32FileInfoHelper();
+ }
+ else
+ {
+ Helper = new GenericFileInfoHelper();
+ }
+#endif
+ }
+
+ public abstract bool GetFileInfo(string fileName, IntPtr fileHandle, out DateTime lastWriteTime, out long fileLength);
+ }
+
+#if !NETCF
+ internal class Win32FileInfoHelper : FileInfoHelper
+ {
+ public override bool GetFileInfo(string fileName, IntPtr fileHandle, out DateTime lastWriteTime, out long fileLength)
+ {
+ Win32FileHelper.BY_HANDLE_FILE_INFORMATION fi;
+
+ if (Win32FileHelper.GetFileInformationByHandle(fileHandle, out fi))
+ {
+ lastWriteTime = DateTime.FromFileTime(fi.ftLastWriteTime);
+ fileLength = fi.nFileSizeLow + (((long)fi.nFileSizeHigh) << 32);
+ return true;
+ }
+ else
+ {
+ lastWriteTime = DateTime.MinValue;
+ fileLength = -1;
+ return false;
+ }
+ }
+ }
+#endif
+
+ internal class GenericFileInfoHelper : FileInfoHelper
+ {
+ public override bool GetFileInfo(string fileName, IntPtr fileHandle, out DateTime lastWriteTime, out long fileLength)
+ {
+ FileInfo fi = new FileInfo(fileName);
+ if (fi.Exists)
+ {
+ fileLength = fi.Length;
+ lastWriteTime = fi.LastWriteTime;
+ return true;
+ }
+ else
+ {
+ fileLength = -1;
+ lastWriteTime = DateTime.MinValue;
+ return false;
+ }
+ }
+ }
+}
diff --git a/src/NLog/Internal/FilterDictionary.cs b/src/NLog/Internal/FilterDictionary.cs
new file mode 100644
index 0000000..2609514
--- /dev/null
+++ b/src/NLog/Internal/FilterDictionary.cs
@@ -0,0 +1,164 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+using NLog.Config;
+using NLog.Filters;
+
+namespace NLog.Internal
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A dictionary with keys of type string and values of type Filter
+ /// </summary>
+ internal class FilterDictionary: System.Collections.DictionaryBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the FilterDictionary class
+ /// </summary>
+ public FilterDictionary()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Gets or sets the Filter associated with the given string
+ /// </summary>
+ /// <param name="key">
+ /// The string whose value to get or set.
+ /// </param>
+ public virtual Filter this[string key]
+ {
+ get { return (Filter)this.Dictionary[key]; }
+ set { this.Dictionary[key] = value; }
+ }
+
+ /// <summary>
+ /// Adds an element with the specified key and value to this FilterDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to add.
+ /// </param>
+ /// <param name="value">
+ /// The Filter value of the element to add.
+ /// </param>
+ public virtual void Add(string key, Filter value)
+ {
+ this.Dictionary.Add(key, value);
+ }
+
+ /// <summary>
+ /// Determines whether this FilterDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this FilterDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this FilterDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool Contains(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this FilterDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this FilterDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this FilterDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsKey(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this FilterDictionary contains a specific value.
+ /// </summary>
+ /// <param name="value">
+ /// The Filter value to locate in this FilterDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this FilterDictionary contains an element with the specified value;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsValue(Filter value)
+ {
+ foreach (Filter item in this.Dictionary.Values)
+ {
+ if (item == value)
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Removes the element with the specified key from this FilterDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to remove.
+ /// </param>
+ public virtual void Remove(string key)
+ {
+ this.Dictionary.Remove(key);
+ }
+
+ /// <summary>
+ /// Gets a collection containing the keys in this FilterDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Keys
+ {
+ get { return this.Dictionary.Keys; }
+ }
+
+ /// <summary>
+ /// Gets a collection containing the values in this FilterDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Values
+ {
+ get { return this.Dictionary.Values; }
+ }
+ }
+}
diff --git a/src/NLog/Internal/FormHelper.cs b/src/NLog/Internal/FormHelper.cs
new file mode 100644
index 0000000..daf4de5
--- /dev/null
+++ b/src/NLog/Internal/FormHelper.cs
@@ -0,0 +1,130 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !MONO && !NETCF_1_0
+
+using System;
+using System.Text;
+using System.Windows.Forms;
+
+namespace NLog.Internal
+{
+ /// <summary>
+ /// Form helper
+ /// </summary>
+ class FormHelper
+ {
+ /// <summary>
+ /// Finds control embended on searchControl
+ /// </summary>
+ /// <param name="name">name of Control</param>
+ /// <param name="searchControl">Control in which we're searching for control</param>
+ /// <returns>null if no control has been found</returns>
+ public static Control FindControl(string name, Control searchControl)
+ {
+ if (searchControl.Name == name)
+ return searchControl;
+
+ foreach (Control childControl in searchControl.Controls)
+ {
+ Control foundControl = FindControl(name, childControl);
+ if (foundControl != null)
+ return foundControl;
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Finds control of specified type embended on searchControl
+ /// </summary>
+ /// <param name="name">name of Control</param>
+ /// <param name="searchControl">Control in which we're searching for control</param>
+ /// <param name="controlType">Type of control to search</param>
+ /// <returns>null if no control has been found</returns>
+ public static Control FindControl(string name, Control searchControl, Type controlType)
+ {
+ if ((searchControl.Name == name) && (searchControl.GetType() == controlType))
+ return searchControl;
+
+ foreach (Control childControl in searchControl.Controls)
+ {
+ Control foundControl = FindControl(name, childControl, controlType);
+ if (foundControl != null)
+ return foundControl;
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Creates Form
+ /// </summary>
+ /// <param name="name">Name of form</param>
+ /// <param name="width">Width of form</param>
+ /// <param name="height">Height of form</param>
+ /// <param name="show">Auto show form</param>
+ /// <returns>Created form</returns>
+ public static Form CreateForm(string name, int width, int height, bool show)
+ {
+ Form f = new Form();
+ f.Name = name;
+ f.Text = "NLog";
+ f.FormBorderStyle = FormBorderStyle.SizableToolWindow;
+ if (width > 0) f.Width = width;
+ if (height > 0) f.Height = height;
+ if (show) f.Show();
+ return f;
+ }
+
+#if !NETCF
+ /// <summary>
+ /// Creates RichTextBox and docks in parentForm
+ /// </summary>
+ /// <param name="name">Name of RichTextBox</param>
+ /// <param name="parentForm">Form to dock RichTextBox</param>
+ /// <returns>Created RichTextBox</returns>
+ public static RichTextBox CreateRichTextBox(string name, Form parentForm)
+ {
+ RichTextBox rtb = new RichTextBox();
+ rtb.Dock = System.Windows.Forms.DockStyle.Fill;
+ rtb.Location = new System.Drawing.Point(0, 0);
+ rtb.Name = name;
+ rtb.Size = new System.Drawing.Size(parentForm.Width, parentForm.Height);
+ parentForm.Controls.Add(rtb);
+ return rtb;
+ }
+#endif
+ }
+}
+#endif
diff --git a/src/NLog/Internal/HttpUtility.cs b/src/NLog/Internal/HttpUtility.cs
new file mode 100644
index 0000000..9586d37
--- /dev/null
+++ b/src/NLog/Internal/HttpUtility.cs
@@ -0,0 +1,533 @@
+//
+// System.Web.HttpUtility
+//
+// Authors:
+// Patrik Torstensson (Patrik.Torstensson at labs2.com)
+// Wictor Wilén (decode/encode functions) (wictor at ibizkit.se)
+// Tim Coleman (tim at timcoleman.com)
+// Gonzalo Paniagua Javier (gonzalo at ximian.com)
+//
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.IO;
+using System.Security.Permissions;
+using System.Text;
+
+#if NETCF
+
+namespace System.Web
+{
+ internal sealed class HttpUtility
+ {
+
+ #region Fields
+
+ static Hashtable entities;
+ static object lock_ = new object();
+
+ #endregion // Fields
+
+ static Hashtable Entities
+ {
+ get
+ {
+ lock (lock_)
+ {
+ if (entities == null)
+ InitEntities();
+
+ return entities;
+ }
+ }
+ }
+
+ #region Constructors
+
+ static void InitEntities()
+ {
+ // Build the hash table of HTML entity references. This list comes
+ // from the HTML 4.01 W3C recommendation.
+ entities = new Hashtable();
+ entities.Add("nbsp", '\u00A0');
+ entities.Add("iexcl", '\u00A1');
+ entities.Add("cent", '\u00A2');
+ entities.Add("pound", '\u00A3');
+ entities.Add("curren", '\u00A4');
+ entities.Add("yen", '\u00A5');
+ entities.Add("brvbar", '\u00A6');
+ entities.Add("sect", '\u00A7');
+ entities.Add("uml", '\u00A8');
+ entities.Add("copy", '\u00A9');
+ entities.Add("ordf", '\u00AA');
+ entities.Add("laquo", '\u00AB');
+ entities.Add("not", '\u00AC');
+ entities.Add("shy", '\u00AD');
+ entities.Add("reg", '\u00AE');
+ entities.Add("macr", '\u00AF');
+ entities.Add("deg", '\u00B0');
+ entities.Add("plusmn", '\u00B1');
+ entities.Add("sup2", '\u00B2');
+ entities.Add("sup3", '\u00B3');
+ entities.Add("acute", '\u00B4');
+ entities.Add("micro", '\u00B5');
+ entities.Add("para", '\u00B6');
+ entities.Add("middot", '\u00B7');
+ entities.Add("cedil", '\u00B8');
+ entities.Add("sup1", '\u00B9');
+ entities.Add("ordm", '\u00BA');
+ entities.Add("raquo", '\u00BB');
+ entities.Add("frac14", '\u00BC');
+ entities.Add("frac12", '\u00BD');
+ entities.Add("frac34", '\u00BE');
+ entities.Add("iquest", '\u00BF');
+ entities.Add("Agrave", '\u00C0');
+ entities.Add("Aacute", '\u00C1');
+ entities.Add("Acirc", '\u00C2');
+ entities.Add("Atilde", '\u00C3');
+ entities.Add("Auml", '\u00C4');
+ entities.Add("Aring", '\u00C5');
+ entities.Add("AElig", '\u00C6');
+ entities.Add("Ccedil", '\u00C7');
+ entities.Add("Egrave", '\u00C8');
+ entities.Add("Eacute", '\u00C9');
+ entities.Add("Ecirc", '\u00CA');
+ entities.Add("Euml", '\u00CB');
+ entities.Add("Igrave", '\u00CC');
+ entities.Add("Iacute", '\u00CD');
+ entities.Add("Icirc", '\u00CE');
+ entities.Add("Iuml", '\u00CF');
+ entities.Add("ETH", '\u00D0');
+ entities.Add("Ntilde", '\u00D1');
+ entities.Add("Ograve", '\u00D2');
+ entities.Add("Oacute", '\u00D3');
+ entities.Add("Ocirc", '\u00D4');
+ entities.Add("Otilde", '\u00D5');
+ entities.Add("Ouml", '\u00D6');
+ entities.Add("times", '\u00D7');
+ entities.Add("Oslash", '\u00D8');
+ entities.Add("Ugrave", '\u00D9');
+ entities.Add("Uacute", '\u00DA');
+ entities.Add("Ucirc", '\u00DB');
+ entities.Add("Uuml", '\u00DC');
+ entities.Add("Yacute", '\u00DD');
+ entities.Add("THORN", '\u00DE');
+ entities.Add("szlig", '\u00DF');
+ entities.Add("agrave", '\u00E0');
+ entities.Add("aacute", '\u00E1');
+ entities.Add("acirc", '\u00E2');
+ entities.Add("atilde", '\u00E3');
+ entities.Add("auml", '\u00E4');
+ entities.Add("aring", '\u00E5');
+ entities.Add("aelig", '\u00E6');
+ entities.Add("ccedil", '\u00E7');
+ entities.Add("egrave", '\u00E8');
+ entities.Add("eacute", '\u00E9');
+ entities.Add("ecirc", '\u00EA');
+ entities.Add("euml", '\u00EB');
+ entities.Add("igrave", '\u00EC');
+ entities.Add("iacute", '\u00ED');
+ entities.Add("icirc", '\u00EE');
+ entities.Add("iuml", '\u00EF');
+ entities.Add("eth", '\u00F0');
+ entities.Add("ntilde", '\u00F1');
+ entities.Add("ograve", '\u00F2');
+ entities.Add("oacute", '\u00F3');
+ entities.Add("ocirc", '\u00F4');
+ entities.Add("otilde", '\u00F5');
+ entities.Add("ouml", '\u00F6');
+ entities.Add("divide", '\u00F7');
+ entities.Add("oslash", '\u00F8');
+ entities.Add("ugrave", '\u00F9');
+ entities.Add("uacute", '\u00FA');
+ entities.Add("ucirc", '\u00FB');
+ entities.Add("uuml", '\u00FC');
+ entities.Add("yacute", '\u00FD');
+ entities.Add("thorn", '\u00FE');
+ entities.Add("yuml", '\u00FF');
+ entities.Add("fnof", '\u0192');
+ entities.Add("Alpha", '\u0391');
+ entities.Add("Beta", '\u0392');
+ entities.Add("Gamma", '\u0393');
+ entities.Add("Delta", '\u0394');
+ entities.Add("Epsilon", '\u0395');
+ entities.Add("Zeta", '\u0396');
+ entities.Add("Eta", '\u0397');
+ entities.Add("Theta", '\u0398');
+ entities.Add("Iota", '\u0399');
+ entities.Add("Kappa", '\u039A');
+ entities.Add("Lambda", '\u039B');
+ entities.Add("Mu", '\u039C');
+ entities.Add("Nu", '\u039D');
+ entities.Add("Xi", '\u039E');
+ entities.Add("Omicron", '\u039F');
+ entities.Add("Pi", '\u03A0');
+ entities.Add("Rho", '\u03A1');
+ entities.Add("Sigma", '\u03A3');
+ entities.Add("Tau", '\u03A4');
+ entities.Add("Upsilon", '\u03A5');
+ entities.Add("Phi", '\u03A6');
+ entities.Add("Chi", '\u03A7');
+ entities.Add("Psi", '\u03A8');
+ entities.Add("Omega", '\u03A9');
+ entities.Add("alpha", '\u03B1');
+ entities.Add("beta", '\u03B2');
+ entities.Add("gamma", '\u03B3');
+ entities.Add("delta", '\u03B4');
+ entities.Add("epsilon", '\u03B5');
+ entities.Add("zeta", '\u03B6');
+ entities.Add("eta", '\u03B7');
+ entities.Add("theta", '\u03B8');
+ entities.Add("iota", '\u03B9');
+ entities.Add("kappa", '\u03BA');
+ entities.Add("lambda", '\u03BB');
+ entities.Add("mu", '\u03BC');
+ entities.Add("nu", '\u03BD');
+ entities.Add("xi", '\u03BE');
+ entities.Add("omicron", '\u03BF');
+ entities.Add("pi", '\u03C0');
+ entities.Add("rho", '\u03C1');
+ entities.Add("sigmaf", '\u03C2');
+ entities.Add("sigma", '\u03C3');
+ entities.Add("tau", '\u03C4');
+ entities.Add("upsilon", '\u03C5');
+ entities.Add("phi", '\u03C6');
+ entities.Add("chi", '\u03C7');
+ entities.Add("psi", '\u03C8');
+ entities.Add("omega", '\u03C9');
+ entities.Add("thetasym", '\u03D1');
+ entities.Add("upsih", '\u03D2');
+ entities.Add("piv", '\u03D6');
+ entities.Add("bull", '\u2022');
+ entities.Add("hellip", '\u2026');
+ entities.Add("prime", '\u2032');
+ entities.Add("Prime", '\u2033');
+ entities.Add("oline", '\u203E');
+ entities.Add("frasl", '\u2044');
+ entities.Add("weierp", '\u2118');
+ entities.Add("image", '\u2111');
+ entities.Add("real", '\u211C');
+ entities.Add("trade", '\u2122');
+ entities.Add("alefsym", '\u2135');
+ entities.Add("larr", '\u2190');
+ entities.Add("uarr", '\u2191');
+ entities.Add("rarr", '\u2192');
+ entities.Add("darr", '\u2193');
+ entities.Add("harr", '\u2194');
+ entities.Add("crarr", '\u21B5');
+ entities.Add("lArr", '\u21D0');
+ entities.Add("uArr", '\u21D1');
+ entities.Add("rArr", '\u21D2');
+ entities.Add("dArr", '\u21D3');
+ entities.Add("hArr", '\u21D4');
+ entities.Add("forall", '\u2200');
+ entities.Add("part", '\u2202');
+ entities.Add("exist", '\u2203');
+ entities.Add("empty", '\u2205');
+ entities.Add("nabla", '\u2207');
+ entities.Add("isin", '\u2208');
+ entities.Add("notin", '\u2209');
+ entities.Add("ni", '\u220B');
+ entities.Add("prod", '\u220F');
+ entities.Add("sum", '\u2211');
+ entities.Add("minus", '\u2212');
+ entities.Add("lowast", '\u2217');
+ entities.Add("radic", '\u221A');
+ entities.Add("prop", '\u221D');
+ entities.Add("infin", '\u221E');
+ entities.Add("ang", '\u2220');
+ entities.Add("and", '\u2227');
+ entities.Add("or", '\u2228');
+ entities.Add("cap", '\u2229');
+ entities.Add("cup", '\u222A');
+ entities.Add("int", '\u222B');
+ entities.Add("there4", '\u2234');
+ entities.Add("sim", '\u223C');
+ entities.Add("cong", '\u2245');
+ entities.Add("asymp", '\u2248');
+ entities.Add("ne", '\u2260');
+ entities.Add("equiv", '\u2261');
+ entities.Add("le", '\u2264');
+ entities.Add("ge", '\u2265');
+ entities.Add("sub", '\u2282');
+ entities.Add("sup", '\u2283');
+ entities.Add("nsub", '\u2284');
+ entities.Add("sube", '\u2286');
+ entities.Add("supe", '\u2287');
+ entities.Add("oplus", '\u2295');
+ entities.Add("otimes", '\u2297');
+ entities.Add("perp", '\u22A5');
+ entities.Add("sdot", '\u22C5');
+ entities.Add("lceil", '\u2308');
+ entities.Add("rceil", '\u2309');
+ entities.Add("lfloor", '\u230A');
+ entities.Add("rfloor", '\u230B');
+ entities.Add("lang", '\u2329');
+ entities.Add("rang", '\u232A');
+ entities.Add("loz", '\u25CA');
+ entities.Add("spades", '\u2660');
+ entities.Add("clubs", '\u2663');
+ entities.Add("hearts", '\u2665');
+ entities.Add("diams", '\u2666');
+ entities.Add("quot", '\u0022');
+ entities.Add("amp", '\u0026');
+ entities.Add("lt", '\u003C');
+ entities.Add("gt", '\u003E');
+ entities.Add("OElig", '\u0152');
+ entities.Add("oelig", '\u0153');
+ entities.Add("Scaron", '\u0160');
+ entities.Add("scaron", '\u0161');
+ entities.Add("Yuml", '\u0178');
+ entities.Add("circ", '\u02C6');
+ entities.Add("tilde", '\u02DC');
+ entities.Add("ensp", '\u2002');
+ entities.Add("emsp", '\u2003');
+ entities.Add("thinsp", '\u2009');
+ entities.Add("zwnj", '\u200C');
+ entities.Add("zwj", '\u200D');
+ entities.Add("lrm", '\u200E');
+ entities.Add("rlm", '\u200F');
+ entities.Add("ndash", '\u2013');
+ entities.Add("mdash", '\u2014');
+ entities.Add("lsquo", '\u2018');
+ entities.Add("rsquo", '\u2019');
+ entities.Add("sbquo", '\u201A');
+ entities.Add("ldquo", '\u201C');
+ entities.Add("rdquo", '\u201D');
+ entities.Add("bdquo", '\u201E');
+ entities.Add("dagger", '\u2020');
+ entities.Add("Dagger", '\u2021');
+ entities.Add("permil", '\u2030');
+ entities.Add("lsaquo", '\u2039');
+ entities.Add("rsaquo", '\u203A');
+ entities.Add("euro", '\u20AC');
+ }
+
+ public HttpUtility()
+ {
+ }
+
+ #endregion // Constructors
+
+ #region Methods
+
+ private static int GetInt(byte b)
+ {
+ char c = (char)b;
+ if (c >= '0' && c <= '9')
+ return c - '0';
+
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+
+ return -1;
+ }
+
+ public static string UrlEncode(string str)
+ {
+ return UrlEncode(str, Encoding.UTF8);
+ }
+
+ public static string UrlEncode(string s, Encoding Enc)
+ {
+ if (s == null)
+ return null;
+
+ if (s == "")
+ return "";
+
+ byte[] bytes = Enc.GetBytes(s);
+ return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, 0, bytes.Length), 0, bytes.Length);
+ }
+
+ public static string UrlEncode(byte[] bytes)
+ {
+ if (bytes == null)
+ return null;
+
+ if (bytes.Length == 0)
+ return "";
+
+ return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, 0, bytes.Length), 0, bytes.Length);
+ }
+
+ public static string UrlEncode(byte[] bytes, int offset, int count)
+ {
+ if (bytes == null)
+ return null;
+
+ if (bytes.Length == 0)
+ return "";
+
+ return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, offset, count), offset, count);
+ }
+
+ public static byte[] UrlEncodeToBytes(string str)
+ {
+ return UrlEncodeToBytes(str, Encoding.UTF8);
+ }
+
+ public static byte[] UrlEncodeToBytes(string str, Encoding e)
+ {
+ if (str == null)
+ return null;
+
+ if (str == "")
+ return new byte[0];
+
+ byte[] bytes = e.GetBytes(str);
+ return UrlEncodeToBytes(bytes, 0, bytes.Length);
+ }
+
+ public static byte[] UrlEncodeToBytes(byte[] bytes)
+ {
+ if (bytes == null)
+ return null;
+
+ if (bytes.Length == 0)
+ return new byte[0];
+
+ return UrlEncodeToBytes(bytes, 0, bytes.Length);
+ }
+
+ static char[] hexChars = "0123456789abcdef".ToCharArray();
+ const string notEncoded = "!'()*-._";
+
+ static void UrlEncodeChar(char c, Stream result, bool isUnicode)
+ {
+ if (c > 255)
+ {
+ //FIXME: what happens when there is an internal error?
+ //if (!isUnicode)
+ // throw new ArgumentOutOfRangeException ("c", c, "c must be less than 256");
+ int idx;
+ int i = (int)c;
+
+ result.WriteByte((byte)'%');
+ result.WriteByte((byte)'u');
+ idx = i >> 12;
+ result.WriteByte((byte)hexChars[idx]);
+ idx = (i >> 8) & 0x0F;
+ result.WriteByte((byte)hexChars[idx]);
+ idx = (i >> 4) & 0x0F;
+ result.WriteByte((byte)hexChars[idx]);
+ idx = i & 0x0F;
+ result.WriteByte((byte)hexChars[idx]);
+ return;
+ }
+
+ if (c > ' ' && notEncoded.IndexOf(c) != -1)
+ {
+ result.WriteByte((byte)c);
+ return;
+ }
+ if (c == ' ')
+ {
+ result.WriteByte((byte)'+');
+ return;
+ }
+ if ((c < '0') ||
+ (c < 'A' && c > '9') ||
+ (c > 'Z' && c < 'a') ||
+ (c > 'z'))
+ {
+ if (isUnicode && c > 127)
+ {
+ result.WriteByte((byte)'%');
+ result.WriteByte((byte)'u');
+ result.WriteByte((byte)'0');
+ result.WriteByte((byte)'0');
+ }
+ else
+ result.WriteByte((byte)'%');
+
+ int idx = ((int)c) >> 4;
+ result.WriteByte((byte)hexChars[idx]);
+ idx = ((int)c) & 0x0F;
+ result.WriteByte((byte)hexChars[idx]);
+ }
+ else
+ result.WriteByte((byte)c);
+ }
+
+ public static byte[] UrlEncodeToBytes(byte[] bytes, int offset, int count)
+ {
+ if (bytes == null)
+ return null;
+
+ int len = bytes.Length;
+ if (len == 0)
+ return new byte[0];
+
+ if (offset < 0 || offset >= len)
+ throw new ArgumentOutOfRangeException("offset");
+
+ if (count < 0 || count > len - offset)
+ throw new ArgumentOutOfRangeException("count");
+
+ MemoryStream result = new MemoryStream(count);
+ int end = offset + count;
+ for (int i = offset; i < end; i++)
+ UrlEncodeChar((char)bytes[i], result, false);
+
+ return result.ToArray();
+ }
+
+ public static string UrlEncodeUnicode(string str)
+ {
+ if (str == null)
+ return null;
+
+
+ byte [] bytes = Encoding.ASCII.GetBytes (str);
+ bytes = UrlEncodeToBytes (bytes, 0, bytes.Length);
+ return Encoding.ASCII.GetString(bytes, 0, bytes.Length);
+ }
+
+ public static byte[] UrlEncodeUnicodeToBytes(string str)
+ {
+ if (str == null)
+ return null;
+
+ if (str == "")
+ return new byte[0];
+
+ MemoryStream result = new MemoryStream(str.Length);
+ foreach (char c in str)
+ {
+ UrlEncodeChar(c, result, true);
+ }
+ return result.ToArray();
+ }
+
+ #endregion // Methods
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/NLog/Internal/InternalLogger.cs b/src/NLog/Internal/InternalLogger.cs
new file mode 100644
index 0000000..3bc8974
--- /dev/null
+++ b/src/NLog/Internal/InternalLogger.cs
@@ -0,0 +1,499 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Configuration;
+using System.Collections;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+using NLog.Config;
+
+namespace NLog.Internal
+{
+ /// <summary>
+ /// NLog internal logger
+ /// </summary>
+ public sealed class InternalLogger
+ {
+ static LogLevel _logLevel = LogLevel.Info;
+ static bool _logToConsole = false;
+#if !NETCF_1_0
+ static bool _logToConsoleError = false;
+#endif
+ static string _logFile = null;
+
+ /// <summary>
+ /// Internal log level.
+ /// </summary>
+ public static LogLevel LogLevel
+ {
+ get { return _logLevel; }
+ set { _logLevel = value; }
+ }
+
+ /// <summary>
+ /// Log internal messages to the console.
+ /// </summary>
+ public static bool LogToConsole
+ {
+ get { return _logToConsole; }
+ set { _logToConsole = value; }
+ }
+
+#if !NETCF_1_0
+ /// <summary>
+ /// Log internal messages to the console error stream.
+ /// </summary>
+ public static bool LogToConsoleError
+ {
+ get { return _logToConsoleError; }
+ set { _logToConsoleError = value; }
+ }
+#endif
+ /// <summary>
+ /// The name of the internal log file.
+ /// </summary>
+ /// <remarks><see langword="null" /> value disables internal logging to a file.</remarks>
+ public static string LogFile
+ {
+ get { return _logFile; }
+ set
+ {
+#if !NETCF
+ string baseDir = AppDomain.CurrentDomain.BaseDirectory;
+#else
+ string baseDir = CompactFrameworkHelper.GetExeBaseDir();
+#endif
+ _logFile = Path.Combine(baseDir, value);
+ }
+ }
+
+#if !NETCF
+
+ static string GetSetting(string configName, string envName)
+ {
+#if DOTNET_2_0
+ string setting = ConfigurationManager.AppSettings[configName];
+#else
+ string setting = ConfigurationSettings.AppSettings[configName];
+#endif
+ if (setting == null)
+ {
+ try
+ {
+ setting = Environment.GetEnvironmentVariable(envName);
+ }
+ catch
+ {
+ // ignore
+ }
+ }
+ return setting;
+ }
+
+ static InternalLogger()
+ {
+ string setting = GetSetting("nlog.internalLogToConsole", "NLOG_INTERNAL_LOG_TO_CONSOLE");
+ if (setting != null)
+ {
+ try
+ {
+ LogToConsole = Convert.ToBoolean(setting);
+ }
+ catch
+ {
+ // ignore
+ }
+ }
+
+#if !NETCF_1_0
+ setting = GetSetting("nlog.internalLogToConsoleError", "NLOG_INTERNAL_LOG_TO_CONSOLE_ERROR");
+ if (setting != null)
+ {
+ try
+ {
+ LogToConsoleError = Convert.ToBoolean(setting);
+ }
+ catch
+ {
+ // ignore
+ }
+ }
+#endif
+
+ setting = GetSetting("nlog.internalLogLevel", "NLOG_INTERNAL_LOG_LEVEL");
+ if (setting != null)
+ {
+ try
+ {
+ LogLevel = LogLevel.FromString(setting);
+ }
+ catch
+ {
+ // ignore
+ }
+ }
+
+ setting = GetSetting("nlog.internalLogFile", "NLOG_INTERNAL_LOG_FILE");
+ if (setting != null)
+ {
+ try
+ {
+ LogFile = setting;
+ }
+ catch
+ {
+ // ignore
+ }
+ }
+
+ Info("NLog internal logger initialized.");
+ }
+#endif
+
+ private InternalLogger(){}
+
+ private static void Write(LogLevel level, IFormatProvider formatProvider, string message, object[]args)
+ {
+ if (level < _logLevel)
+ return ;
+
+ if (_logFile == null && !_logToConsole
+#if !NETCF_1_0
+ && !_logToConsoleError
+#endif
+ )
+ return ;
+
+ try
+ {
+ string formattedMessage = message;
+ if (args != null)
+ formattedMessage = String.Format(formatProvider, message, args);
+
+ StringBuilder builder = new StringBuilder(message.Length + 32);
+ builder.Append(CurrentTimeGetter.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff", CultureInfo.InvariantCulture));
+ builder.Append(" ");
+ builder.Append(level.ToString());
+ builder.Append(" ");
+ builder.Append(formattedMessage);
+ string msg = builder.ToString();
+
+ if (_logFile != null)
+ {
+ using(TextWriter textWriter = File.AppendText(_logFile))
+ {
+ textWriter.WriteLine(msg);
+ }
+ }
+
+ if (_logToConsole)
+ {
+ Console.WriteLine(msg);
+ }
+
+#if !NETCF_1_0
+ if (_logToConsoleError)
+ {
+ Console.Error.WriteLine(msg);
+ }
+#endif
+ }
+ catch
+ {
+ // we have no place to log the message to so we ignore it
+ }
+ }
+
+ /// <summary>
+ /// Returns true when internal log level includes Trace messages
+ /// </summary>
+ public static bool IsTraceEnabled
+ {
+ get { return LogLevel.Trace >= _logLevel; }
+ }
+
+ /// <summary>
+ /// Returns true when internal log level includes Debug messages
+ /// </summary>
+ public static bool IsDebugEnabled
+ {
+ get { return LogLevel.Debug >= _logLevel; }
+ }
+ /// <summary>
+ /// Returns true when internal log level includes Info messages
+ /// </summary>
+ public static bool IsInfoEnabled
+ {
+ get { return LogLevel.Info >= _logLevel; }
+ }
+ /// <summary>
+ /// Returns true when internal log level includes Warn messages
+ /// </summary>
+ public static bool IsWarnEnabled
+ {
+ get { return LogLevel.Warn >= _logLevel; }
+ }
+ /// <summary>
+ /// Returns true when internal log level includes Error messages
+ /// </summary>
+ public static bool IsErrorEnabled
+ {
+ get { return LogLevel.Error >= _logLevel; }
+ }
+ /// <summary>
+ /// Returns true when internal log level includes Fatal messages
+ /// </summary>
+ public static bool IsFatalEnabled
+ {
+ get { return LogLevel.Fatal >= _logLevel; }
+ }
+
+ /// <summary>
+ /// Logs the specified message at the specified level.
+ /// </summary>
+ /// <param name="level">Log level.</param>
+ /// <param name="formatProvider">Format provider to be used for formatting.</param>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Log(LogLevel level, IFormatProvider formatProvider, string message, params object[]args)
+ {
+ Write(level, formatProvider, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the specified level.
+ /// </summary>
+ /// <param name="level">Log level.</param>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Log(LogLevel level, string message, params object[]args)
+ {
+ Write(level, null, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the specified level.
+ /// </summary>
+ /// <param name="level">Log level.</param>
+ /// <param name="message">Log message.</param>
+ public static void Log(LogLevel level, string message)
+ {
+ Write(level, null, message, null);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Trace level.
+ /// </summary>
+ /// <param name="formatProvider">Format provider to be used for formatting.</param>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Trace(IFormatProvider formatProvider, string message, params object[]args)
+ {
+ Write(LogLevel.Trace, formatProvider, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Trace level.
+ /// </summary>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Trace(string message, params object[]args)
+ {
+ Write(LogLevel.Trace, null, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Trace level.
+ /// </summary>
+ /// <param name="message">Log message.</param>
+ public static void Trace(string message)
+ {
+ Write(LogLevel.Trace, null, message, null);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Debug level.
+ /// </summary>
+ /// <param name="formatProvider">Format provider to be used for formatting.</param>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Debug(IFormatProvider formatProvider, string message, params object[]args)
+ {
+ Write(LogLevel.Debug, formatProvider, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Debug level.
+ /// </summary>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Debug(string message, params object[]args)
+ {
+ Write(LogLevel.Debug, null, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Debug level.
+ /// </summary>
+ /// <param name="message">Log message.</param>
+ public static void Debug(string message)
+ {
+ Write(LogLevel.Debug, null, message, null);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Info level.
+ /// </summary>
+ /// <param name="formatProvider">Format provider to be used for formatting.</param>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Info(IFormatProvider formatProvider, string message, params object[]args)
+ {
+ Write(LogLevel.Info, formatProvider, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Info level.
+ /// </summary>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Info(string message, params object[]args)
+ {
+ Write(LogLevel.Info, null, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Info level.
+ /// </summary>
+ /// <param name="message">Log message.</param>
+ public static void Info(string message)
+ {
+ Write(LogLevel.Info, null, message, null);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Warn level.
+ /// </summary>
+ /// <param name="formatProvider">Format provider to be used for formatting.</param>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Warn(IFormatProvider formatProvider, string message, params object[]args)
+ {
+ Write(LogLevel.Warn, formatProvider, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Warn level.
+ /// </summary>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Warn(string message, params object[]args)
+ {
+ Write(LogLevel.Warn, null, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Warn level.
+ /// </summary>
+ /// <param name="message">Log message.</param>
+ public static void Warn(string message)
+ {
+ Write(LogLevel.Warn, null, message, null);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Error level.
+ /// </summary>
+ /// <param name="formatProvider">Format provider to be used for formatting.</param>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Error(IFormatProvider formatProvider, string message, params object[]args)
+ {
+ Write(LogLevel.Error, formatProvider, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Error level.
+ /// </summary>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Error(string message, params object[]args)
+ {
+ Write(LogLevel.Error, null, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Error level.
+ /// </summary>
+ /// <param name="message">Log message.</param>
+ public static void Error(string message)
+ {
+ Write(LogLevel.Error, null, message, null);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Fatal level.
+ /// </summary>
+ /// <param name="formatProvider">Format provider to be used for formatting.</param>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Fatal(IFormatProvider formatProvider, string message, params object[]args)
+ {
+ Write(LogLevel.Fatal, formatProvider, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Fatal level.
+ /// </summary>
+ /// <param name="message">Message which may include positional parameters.</param>
+ /// <param name="args">Arguments.</param>
+ public static void Fatal(string message, params object[]args)
+ {
+ Write(LogLevel.Fatal, null, message, args);
+ }
+
+ /// <summary>
+ /// Logs the specified message at the Fatal level.
+ /// </summary>
+ /// <param name="message">Log message.</param>
+ public static void Fatal(string message)
+ {
+ Write(LogLevel.Fatal, null, message, null);
+ }
+ }
+}
diff --git a/src/NLog/Internal/LayoutRendererDictionary.cs b/src/NLog/Internal/LayoutRendererDictionary.cs
new file mode 100644
index 0000000..093112b
--- /dev/null
+++ b/src/NLog/Internal/LayoutRendererDictionary.cs
@@ -0,0 +1,164 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+using NLog.Config;
+using NLog.LayoutRenderers;
+
+namespace NLog.Internal
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A dictionary with keys of type string and values of type LayoutRenderer
+ /// </summary>
+ internal class LayoutRendererDictionary: System.Collections.DictionaryBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the LayoutRendererDictionary class
+ /// </summary>
+ public LayoutRendererDictionary()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Gets or sets the LayoutRenderer associated with the given string
+ /// </summary>
+ /// <param name="key">
+ /// The string whose value to get or set.
+ /// </param>
+ public virtual LayoutRenderer this[string key]
+ {
+ get { return (LayoutRenderer)this.Dictionary[key]; }
+ set { this.Dictionary[key] = value; }
+ }
+
+ /// <summary>
+ /// Adds an element with the specified key and value to this LayoutRendererDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to add.
+ /// </param>
+ /// <param name="value">
+ /// The LayoutRenderer value of the element to add.
+ /// </param>
+ public virtual void Add(string key, LayoutRenderer value)
+ {
+ this.Dictionary.Add(key, value);
+ }
+
+ /// <summary>
+ /// Determines whether this LayoutRendererDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this LayoutRendererDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this LayoutRendererDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool Contains(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this LayoutRendererDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this LayoutRendererDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this LayoutRendererDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsKey(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this LayoutRendererDictionary contains a specific value.
+ /// </summary>
+ /// <param name="value">
+ /// The LayoutRenderer value to locate in this LayoutRendererDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this LayoutRendererDictionary contains an element with the specified value;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsValue(LayoutRenderer value)
+ {
+ foreach (LayoutRenderer item in this.Dictionary.Values)
+ {
+ if (item == value)
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Removes the element with the specified key from this LayoutRendererDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to remove.
+ /// </param>
+ public virtual void Remove(string key)
+ {
+ this.Dictionary.Remove(key);
+ }
+
+ /// <summary>
+ /// Gets a collection containing the keys in this LayoutRendererDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Keys
+ {
+ get { return this.Dictionary.Keys; }
+ }
+
+ /// <summary>
+ /// Gets a collection containing the values in this LayoutRendererDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Values
+ {
+ get { return this.Dictionary.Values; }
+ }
+ }
+}
diff --git a/src/NLog/Internal/LogEventInfoBuffer.cs b/src/NLog/Internal/LogEventInfoBuffer.cs
new file mode 100644
index 0000000..9c263fe
--- /dev/null
+++ b/src/NLog/Internal/LogEventInfoBuffer.cs
@@ -0,0 +1,168 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+
+using NLog.Config;
+
+namespace NLog.Internal
+{
+ /// <summary>
+ /// A cyclic buffer of <see cref="LogEventInfo"/> object.
+ /// </summary>
+ public class LogEventInfoBuffer
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="LogEventInfoBuffer"/>, sets the buffer size and grow options.
+ /// </summary>
+ /// <param name="size">Buffer size.</param>
+ /// <param name="growAsNeeded">Whether buffer should grow as it becomes full.</param>
+ /// <param name="growLimit">The maximum number of items that the buffer can grow to.</param>
+ public LogEventInfoBuffer(int size, bool growAsNeeded, int growLimit)
+ {
+ _growAsNeeded = growAsNeeded;
+ _buffer = new LogEventInfo[size];
+ _growLimit = growLimit;
+ _getPointer = 0;
+ _putPointer = 0;
+ }
+
+ private LogEventInfo[] _buffer;
+ private int _getPointer = 0;
+ private int _putPointer = 0;
+ private int _count = 0;
+ private bool _growAsNeeded;
+ private int _growLimit = 0;
+
+ /// <summary>
+ /// Adds the specified log event to the buffer.
+ /// </summary>
+ /// <param name="e">Log event</param>
+ /// <returns>The number of items in the buffer.</returns>
+ public int Append(LogEventInfo e)
+ {
+ lock (this)
+ {
+ // make room for additional item
+
+ if (_count >= _buffer.Length)
+ {
+ if (_growAsNeeded && _buffer.Length < _growLimit)
+ {
+ // create a new buffer, copy data from current
+
+ int newLength = _buffer.Length * 2;
+ if (newLength >= _growLimit)
+ newLength = _growLimit;
+
+ LogEventInfo[] newBuffer = new LogEventInfo[newLength];
+ // InternalLogger.Trace("Enlarging LogEventInfoBuffer from {0} to {1}", _buffer.Length, _buffer.Length * 2);
+ Array.Copy(_buffer, 0, newBuffer, 0, _buffer.Length);
+ _buffer = newBuffer;
+ }
+ else
+ {
+ // lose the oldest item
+ _getPointer = _getPointer + 1;
+ }
+ }
+
+ // put the item
+
+ _putPointer = _putPointer % _buffer.Length;
+ _buffer[_putPointer] = e;
+ _putPointer = _putPointer + 1;
+ _count++;
+ if (_count >= _buffer.Length)
+ _count = _buffer.Length;
+ return _count;
+
+/*
+ InternalLogger.Trace("GetPointer: {0} PutPointer: {1} Count: {2} BufferLength: {3}", _getPointer, _putPointer, _count, _buffer.Length);
+ for (int i = 0; i < _count; ++i)
+ {
+ InternalLogger.Trace("buffer[{0}] = {1}", i, _buffer[(_getPointer + i) % _buffer.Length].Message);
+ }
+
+*/
+
+ //Console.ReadLine();
+ }
+ }
+
+ /// <summary>
+ /// Gets the array of events accumulated in the buffer and clears the buffer as one atomic operation.
+ /// </summary>
+ /// <returns>An array of <see cref="LogEventInfo"/> objects that have been accumulated in the buffer.</returns>
+ /// <remarks>
+ /// In case there are no items in the buffer, the function returns an empty array.
+ /// </remarks>
+ public LogEventInfo[] GetEventsAndClear()
+ {
+ lock (this)
+ {
+ int cnt = _count;
+ LogEventInfo[] returnValue = new LogEventInfo[cnt];
+ // InternalLogger.Trace("GetEventsAndClear({0},{1},{2})", _getPointer, _putPointer, _count);
+ for (int i = 0; i < cnt; ++i)
+ {
+ int p = (_getPointer + i) % _buffer.Length;
+ LogEventInfo e = _buffer[p];
+ _buffer[p] = null; // we don't want memory leaks
+ returnValue[i] = e;
+ }
+ _count = 0;
+ _getPointer = 0;
+ _putPointer = 0;
+ return returnValue;
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of items in the array.
+ /// </summary>
+ public int Size
+ {
+ get { return _buffer.Length; }
+ }
+ }
+}
diff --git a/src/NLog/Internal/LoggerConfiguration.cs b/src/NLog/Internal/LoggerConfiguration.cs
new file mode 100644
index 0000000..3d3925f
--- /dev/null
+++ b/src/NLog/Internal/LoggerConfiguration.cs
@@ -0,0 +1,66 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+using NLog.Config;
+
+namespace NLog.Internal
+{
+ internal class LoggerConfiguration
+ {
+ private TargetWithFilterChain[] _targetsByLevel;
+
+ public LoggerConfiguration(TargetWithFilterChain[] targetsByLevel)
+ {
+ _targetsByLevel = targetsByLevel;
+ }
+
+ public TargetWithFilterChain GetTargetsForLevel(LogLevel level)
+ {
+ return _targetsByLevel[level.Ordinal];
+ }
+
+ public bool IsEnabled(LogLevel level)
+ {
+ return _targetsByLevel[level.Ordinal] != null;
+ }
+
+ }
+}
diff --git a/src/NLog/Internal/LoggerDictionary.cs b/src/NLog/Internal/LoggerDictionary.cs
new file mode 100644
index 0000000..d4905c5
--- /dev/null
+++ b/src/NLog/Internal/LoggerDictionary.cs
@@ -0,0 +1,162 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+using NLog.Config;
+
+namespace NLog.Internal
+{
+ /// <summary>
+ /// A dictionary with keys of type string and values of type Logger
+ /// </summary>
+ internal class LoggerDictionary: System.Collections.DictionaryBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the LoggerDictionary class
+ /// </summary>
+ public LoggerDictionary()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Gets or sets the Logger associated with the given string
+ /// </summary>
+ /// <param name="key">
+ /// The string whose value to get or set.
+ /// </param>
+ public virtual Logger this[string key]
+ {
+ get { return (Logger)this.Dictionary[key]; }
+ set { this.Dictionary[key] = value; }
+ }
+
+ /// <summary>
+ /// Adds an element with the specified key and value to this LoggerDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to add.
+ /// </param>
+ /// <param name="value">
+ /// The Logger value of the element to add.
+ /// </param>
+ public virtual void Add(string key, Logger value)
+ {
+ this.Dictionary.Add(key, value);
+ }
+
+ /// <summary>
+ /// Determines whether this LoggerDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this LoggerDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this LoggerDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool Contains(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this LoggerDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this LoggerDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this LoggerDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsKey(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this LoggerDictionary contains a specific value.
+ /// </summary>
+ /// <param name="value">
+ /// The Logger value to locate in this LoggerDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this LoggerDictionary contains an element with the specified value;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsValue(Logger value)
+ {
+ foreach (Logger item in this.Dictionary.Values)
+ {
+ if (item == value)
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Removes the element with the specified key from this LoggerDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to remove.
+ /// </param>
+ public virtual void Remove(string key)
+ {
+ this.Dictionary.Remove(key);
+ }
+
+ /// <summary>
+ /// Gets a collection containing the keys in this LoggerDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Keys
+ {
+ get { return this.Dictionary.Keys; }
+ }
+
+ /// <summary>
+ /// Gets a collection containing the values in this LoggerDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Values
+ {
+ get { return this.Dictionary.Values; }
+ }
+ }
+}
diff --git a/src/NLog/Internal/MethodInfoDictionary.cs b/src/NLog/Internal/MethodInfoDictionary.cs
new file mode 100644
index 0000000..0452c0b
--- /dev/null
+++ b/src/NLog/Internal/MethodInfoDictionary.cs
@@ -0,0 +1,164 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+using NLog.Config;
+
+namespace NLog.Internal
+{
+ // CLOVER:OFF
+
+ /// <summary>
+ /// A dictionary with keys of type string and values of type MethodInfo
+ /// </summary>
+ internal class MethodInfoDictionary: System.Collections.DictionaryBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the MethodInfoDictionary class
+ /// </summary>
+ public MethodInfoDictionary()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Gets or sets the MethodInfo associated with the given string
+ /// </summary>
+ /// <param name="key">
+ /// The string whose value to get or set.
+ /// </param>
+ public virtual MethodInfo this[string key]
+ {
+ get { return (MethodInfo)this.Dictionary[key]; }
+ set { this.Dictionary[key] = value; }
+ }
+
+ /// <summary>
+ /// Adds an element with the specified key and value to this MethodInfoDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to add.
+ /// </param>
+ /// <param name="value">
+ /// The MethodInfo value of the element to add.
+ /// </param>
+ public virtual void Add(string key, MethodInfo value)
+ {
+ this.Dictionary.Add(key, value);
+ }
+
+ /// <summary>
+ /// Determines whether this MethodInfoDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this MethodInfoDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this MethodInfoDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool Contains(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this MethodInfoDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this MethodInfoDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this MethodInfoDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsKey(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this MethodInfoDictionary contains a specific value.
+ /// </summary>
+ /// <param name="value">
+ /// The MethodInfo value to locate in this MethodInfoDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this MethodInfoDictionary contains an element with the specified value;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsValue(MethodInfo value)
+ {
+ foreach (MethodInfo item in this.Dictionary.Values)
+ {
+ if (item == value)
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Removes the element with the specified key from this MethodInfoDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to remove.
+ /// </param>
+ public virtual void Remove(string key)
+ {
+ this.Dictionary.Remove(key);
+ }
+
+ /// <summary>
+ /// Gets a collection containing the keys in this MethodInfoDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Keys
+ {
+ get { return this.Dictionary.Keys; }
+ }
+
+ /// <summary>
+ /// Gets a collection containing the values in this MethodInfoDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Values
+ {
+ get { return this.Dictionary.Values; }
+ }
+ }
+}
diff --git a/src/NLog/Internal/MultiFileWatcher.cs b/src/NLog/Internal/MultiFileWatcher.cs
new file mode 100644
index 0000000..a66d61c
--- /dev/null
+++ b/src/NLog/Internal/MultiFileWatcher.cs
@@ -0,0 +1,119 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Collections;
+using System.IO;
+
+namespace NLog.Internal
+{
+ internal class MultiFileWatcher: IDisposable
+ {
+ private ArrayList _watchers = new ArrayList();
+
+ public MultiFileWatcher(){}
+
+ public MultiFileWatcher(EventHandler onChange)
+ {
+ OnChange += onChange;
+ }
+
+ public MultiFileWatcher(ICollection fileNames)
+ {
+ Watch(fileNames);
+ }
+
+ public void Dispose()
+ {
+ StopWatching();
+ }
+
+ public void StopWatching()
+ {
+ lock(this)
+ {
+ foreach (FileSystemWatcher watcher in _watchers)
+ {
+ InternalLogger.Info("Stopping file watching for path '{0}' filter '{1}'", watcher.Path, watcher.Filter);
+ watcher.EnableRaisingEvents = false;
+ watcher.Dispose();
+ //Console.WriteLine("aa");
+ }
+ _watchers.Clear();
+ }
+ }
+
+ public void Watch(ICollection fileNames)
+ {
+ if (fileNames == null)
+ return ;
+ foreach (string s in fileNames)
+ {
+ Watch(s);
+ }
+ }
+
+ public void Watch(string fileName)
+ {
+ FileSystemWatcher watcher = new FileSystemWatcher();
+ watcher.Path = Path.GetDirectoryName(fileName);
+ watcher.Filter = Path.GetFileName(fileName);
+ watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.CreationTime | NotifyFilters.Size | NotifyFilters.Security | NotifyFilters.Attributes;
+ watcher.Created += new FileSystemEventHandler(this.OnWatcherChanged);
+ watcher.Changed += new FileSystemEventHandler(this.OnWatcherChanged);
+ watcher.Deleted += new FileSystemEventHandler(this.OnWatcherChanged);
+ watcher.EnableRaisingEvents = true;
+ InternalLogger.Info("Watching path '{0}' filter '{1}' for changes.", watcher.Path, watcher.Filter);
+
+ lock(this)
+ {
+ _watchers.Add(watcher);
+ }
+ }
+
+ private void OnWatcherChanged(object source, FileSystemEventArgs e)
+ {
+ lock(this)
+ {
+ if (OnChange != null)
+ OnChange(source, e);
+ }
+ }
+
+ public event EventHandler OnChange;
+ }
+}
+
+#endif
diff --git a/src/NLog/Internal/NetworkSenders/NetworkSender.cs b/src/NLog/Internal/NetworkSenders/NetworkSender.cs
new file mode 100644
index 0000000..b7cabc6
--- /dev/null
+++ b/src/NLog/Internal/NetworkSenders/NetworkSender.cs
@@ -0,0 +1,146 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Threading;
+
+namespace NLog.Internal.NetworkSenders
+{
+ /// <summary>
+ /// A base class for all network senders. Supports one-way sending of messages
+ /// over various protocols.
+ /// </summary>
+ public abstract class NetworkSender : IDisposable
+ {
+ private string _url;
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="NetworkSender"/> and initializes
+ /// it with the specified URL.
+ /// </summary>
+ /// <param name="url">URL.</param>
+ protected NetworkSender(string url)
+ {
+ _url = url;
+ }
+
+ /// <summary>
+ /// Disposes the <see cref="NetworkSender"/> object.
+ /// </summary>
+ ~NetworkSender()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Creates a new instance of the network sender based on a network URL:
+ /// </summary>
+ /// <param name="url">URL that determines the network sender to be created.</param>
+ /// <returns>A newly created network sender.</returns>
+ /// <remarks>
+ /// If the url starts with <c>tcp://</c> - a new <see cref="TcpNetworkSender" /> is created.<br/>
+ /// If the url starts with <c>udp://</c> - a new <see cref="UdpNetworkSender" /> is created.<br/>
+ /// </remarks>
+ public static NetworkSender Create(string url)
+ {
+ if (url.StartsWith("tcp://"))
+ {
+ return new TcpNetworkSender(url);
+ }
+ if (url.StartsWith("udp://"))
+ {
+ return new UdpNetworkSender(url);
+ }
+ throw new ArgumentException("Unrecognized network address", "url");
+ }
+
+ /// <summary>
+ /// Closes the sender and releases any unmanaged resources.
+ /// </summary>
+ public virtual void Close()
+ {
+ }
+
+ /// <summary>
+ /// Flushes any buffers.
+ /// </summary>
+ public virtual void Flush()
+ {
+ }
+
+ /// <summary>
+ /// The address of the network endpoint.
+ /// </summary>
+ public string Address
+ {
+ get { return _url; }
+ }
+
+ /// <summary>
+ /// Send the given text over the specified protocol.
+ /// </summary>
+ /// <param name="bytes">Bytes to be sent.</param>
+ /// <param name="offset">Offset in buffer</param>
+ /// <param name="length">Number of bytes to send</param>
+ public void Send(byte[] bytes, int offset, int length)
+ {
+ DoSend(bytes, offset, length);
+ }
+
+ /// <summary>
+ /// Actually sends the given text over the specified protocol.
+ /// </summary>
+ /// <param name="bytes">The bytes to be sent.</param>
+ /// <param name="offset">Offset in buffer</param>
+ /// <param name="length">Number of bytes to send</param>
+ /// <remarks>To be overridden in inheriting classes.</remarks>
+ protected abstract void DoSend(byte[] bytes, int offset, int length);
+
+ /// <summary>
+ /// Closes the sender and releases any unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ Close();
+ }
+ }
+ }
+}
diff --git a/src/NLog/Internal/NetworkSenders/TcpNetworkSender.cs b/src/NLog/Internal/NetworkSenders/TcpNetworkSender.cs
new file mode 100644
index 0000000..1381225
--- /dev/null
+++ b/src/NLog/Internal/NetworkSenders/TcpNetworkSender.cs
@@ -0,0 +1,107 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+
+namespace NLog.Internal.NetworkSenders
+{
+ /// <summary>
+ /// Sends messages over a TCP network connection.
+ /// </summary>
+ public class TcpNetworkSender : NetworkSender
+ {
+ private Socket _socket;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="TcpNetworkSender"/> and initializes
+ /// it with the specified URL. Connects to the server specified in the URL.
+ /// </summary>
+ /// <param name="url">URL. Must start with tcp://</param>
+ public TcpNetworkSender(string url) : base(url)
+ {
+ // tcp://hostname:port
+
+ Uri parsedUri = new Uri(url);
+#if NET_2_API
+ IPHostEntry host = Dns.GetHostEntry(parsedUri.Host);
+#else
+ IPHostEntry host = Dns.GetHostByName(parsedUri.Host);
+#endif
+ int port = parsedUri.Port;
+
+#if NETCF_1_0
+ _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+#else
+ _socket = new Socket(host.AddressList[0].AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+#endif
+ _socket.Connect(new IPEndPoint(host.AddressList[0], port));
+ }
+
+ /// <summary>
+ /// Sends the specified text over the connected socket.
+ /// </summary>
+ /// <param name="bytes">The bytes to be sent.</param>
+ /// <param name="offset">Offset in buffer</param>
+ /// <param name="length">Number of bytes to send</param>
+ /// <remarks>To be overridden in inheriting classes.</remarks>
+ protected override void DoSend(byte[] bytes, int offset, int length)
+ {
+ lock (this)
+ {
+ _socket.Send(bytes, offset, length, SocketFlags.None);
+ }
+ }
+
+ /// <summary>
+ /// Closes the socket.
+ /// </summary>
+ public override void Close()
+ {
+ lock (this)
+ {
+ try
+ {
+ _socket.Close();
+ }
+ catch (Exception)
+ {
+ // ignore errors
+ }
+ _socket = null;
+ }
+ }
+ }
+}
diff --git a/src/NLog/Internal/NetworkSenders/UdpNetworkSender.cs b/src/NLog/Internal/NetworkSenders/UdpNetworkSender.cs
new file mode 100644
index 0000000..9539696
--- /dev/null
+++ b/src/NLog/Internal/NetworkSenders/UdpNetworkSender.cs
@@ -0,0 +1,104 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+
+namespace NLog.Internal.NetworkSenders
+{
+ /// <summary>
+ /// Sends messages over the network as UDP datagrams.
+ /// </summary>
+ public class UdpNetworkSender : NetworkSender
+ {
+ private Socket _socket;
+ private IPEndPoint _endpoint;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="UdpNetworkSender"/> and initializes
+ /// it with the specified URL.
+ /// </summary>
+ /// <param name="url">URL. Must start with udp://</param>
+ public UdpNetworkSender(string url) : base(url)
+ {
+ // udp://hostname:port
+
+ Uri parsedUri = new Uri(url);
+#if NET_2_API
+ IPHostEntry host = Dns.GetHostEntry(parsedUri.Host);
+#else
+ IPHostEntry host = Dns.GetHostByName(parsedUri.Host);
+#endif
+ int port = parsedUri.Port;
+
+ _endpoint = new IPEndPoint(host.AddressList[0], port);
+ _socket = new Socket(_endpoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
+ }
+
+ /// <summary>
+ /// Sends the specified text as a UDP datagram.
+ /// </summary>
+ /// <param name="bytes">The bytes to be sent.</param>
+ /// <param name="offset">Offset in buffer</param>
+ /// <param name="length">Number of bytes to send</param>
+ /// <remarks>To be overridden in inheriting classes.</remarks>
+ protected override void DoSend(byte[] bytes, int offset, int length)
+ {
+ lock (this)
+ {
+ _socket.SendTo(bytes, offset, length, SocketFlags.None, _endpoint);
+ }
+ }
+
+ /// <summary>
+ /// Closes the socket.
+ /// </summary>
+ public override void Close()
+ {
+ lock (this)
+ {
+ try
+ {
+ _socket.Close();
+ }
+ catch (Exception)
+ {
+ // ignore errors
+ }
+ _socket = null;
+ }
+ }
+ }
+}
diff --git a/src/NLog/Internal/PlatformDetector.cs b/src/NLog/Internal/PlatformDetector.cs
new file mode 100644
index 0000000..41dc336
--- /dev/null
+++ b/src/NLog/Internal/PlatformDetector.cs
@@ -0,0 +1,268 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Reflection;
+using System.Collections;
+
+using NLog.Config;
+using NLog.Internal;
+
+namespace NLog.Internal
+{
+ internal class PlatformDetector
+ {
+ private static IDictionary _currentFrameworkCompatibleWith = new Hashtable();
+ private static IDictionary _currentOSCompatibleWith = new Hashtable();
+
+ public static bool IsCurrentOSCompatibleWith(RuntimeOS os)
+ {
+ return _currentOSCompatibleWith.Contains(os);
+ }
+
+ public static bool IsCurrentFrameworkCompatibleWith(RuntimeFramework framework)
+ {
+ return _currentFrameworkCompatibleWith.Contains(framework);
+ }
+
+ public static bool IsSupportedOnCurrentRuntime(Type t)
+ {
+ SupportedRuntimeAttribute[] supportedRuntimes =
+ (SupportedRuntimeAttribute[])t.GetCustomAttributes(typeof(SupportedRuntimeAttribute), true);
+
+ NotSupportedRuntimeAttribute[] notSupportedRuntimes =
+ (NotSupportedRuntimeAttribute[])t.GetCustomAttributes(typeof(NotSupportedRuntimeAttribute), true);
+
+ // no attributes defined - we default to Yes.
+ if (supportedRuntimes.Length + notSupportedRuntimes.Length == 0)
+ return true;
+
+ bool supported = false;
+ if (supportedRuntimes.Length == 0)
+ supported = true;
+
+ foreach (SupportedRuntimeAttribute sr in supportedRuntimes)
+ {
+ if (RuntimeMatches(sr))
+ {
+ supported = true;
+ break;
+ }
+ }
+
+ if (supported)
+ {
+ foreach (NotSupportedRuntimeAttribute nsr in notSupportedRuntimes)
+ {
+ if (RuntimeMatches(nsr))
+ {
+ supported = false;
+ break;
+ }
+ }
+ }
+
+ if (!supported)
+ InternalLogger.Debug("{0} is not supported on current runtime.", t.FullName);
+
+ return supported;
+ }
+
+ public static bool IsSupportedOnCurrentRuntime(MethodInfo mi)
+ {
+ SupportedRuntimeAttribute[] supportedRuntimes =
+ (SupportedRuntimeAttribute[])mi.GetCustomAttributes(typeof(SupportedRuntimeAttribute), true);
+
+ NotSupportedRuntimeAttribute[] notSupportedRuntimes =
+ (NotSupportedRuntimeAttribute[])mi.GetCustomAttributes(typeof(NotSupportedRuntimeAttribute), true);
+
+ // no attributes defined - we default to Yes.
+ if (supportedRuntimes.Length + notSupportedRuntimes.Length == 0)
+ return true;
+
+ bool supported = false;
+ if (supportedRuntimes.Length == 0)
+ supported = true;
+
+ foreach (SupportedRuntimeAttribute sr in supportedRuntimes)
+ {
+ if (RuntimeMatches(sr))
+ {
+ supported = true;
+ break;
+ }
+ }
+
+
+
+ if (supported)
+ {
+ foreach (NotSupportedRuntimeAttribute nsr in notSupportedRuntimes)
+ {
+ if (RuntimeMatches(nsr))
+ {
+ supported = false;
+ break;
+ }
+ }
+ }
+
+ if (!supported)
+ InternalLogger.Debug("{0} is not supported on current runtime.", mi.ToString());
+
+ return supported;
+ }
+
+ private static bool RuntimeMatches(SupportedRuntimeAttributeBase sr)
+ {
+ if (_currentFrameworkCompatibleWith.Contains(sr.Framework) && _currentOSCompatibleWith.Contains(sr.OS))
+ {
+ if (sr.MinOSVersion != null)
+ {
+ if (CompareVersion(Environment.OSVersion.Version, sr.MinOSVersion) < 0)
+ return false;
+ }
+ if (sr.MaxOSVersion != null)
+ {
+ if (CompareVersion(Environment.OSVersion.Version, sr.MaxOSVersion) > 0)
+ return false;
+ }
+ if (sr.MinRuntimeVersion != null)
+ {
+ if (CompareVersion(Environment.Version, sr.MinRuntimeVersion) < 0)
+ return false;
+ }
+ if (sr.MaxRuntimeVersion != null)
+ {
+ if (CompareVersion(Environment.Version, sr.MaxRuntimeVersion) > 0)
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private static int CompareVersion(Version v, string v2)
+ {
+ string[] parts = v2.Split('.');
+ int result;
+
+ if (parts.Length > 0)
+ {
+ int p = Convert.ToInt32(parts[0]);
+ result = v.Major.CompareTo(p);
+ if (result != 0)
+ return result;
+ }
+
+ if (parts.Length > 1)
+ {
+ int p = Convert.ToInt32(parts[1]);
+ result = v.Minor.CompareTo(p);
+ if (result != 0)
+ return result;
+ }
+
+ if (parts.Length > 2)
+ {
+ int p = Convert.ToInt32(parts[2]);
+ result = v.Build.CompareTo(p);
+ if (result != 0)
+ return result;
+ }
+
+ if (parts.Length > 3)
+ {
+ int p = Convert.ToInt32(parts[3]);
+ result = v.Revision.CompareTo(p);
+ if (result != 0)
+ return result;
+ }
+
+ return 0;
+ }
+
+ static PlatformDetector()
+ {
+ FindCompatibleFrameworks();
+ FindCompatibleOSes();
+ }
+
+ public static RuntimeFramework GetCurrentRuntimeFramework()
+ {
+#if NETCF
+ return RuntimeFramework.DotNetCompactFramework;
+#else
+ if (Type.GetType("System.MonoType", false) != null)
+ {
+ return RuntimeFramework.Mono;
+ }
+ else
+ {
+ return RuntimeFramework.DotNetFramework;
+ }
+#endif
+ }
+
+ public static RuntimeOS GetCurrentRuntimeOS()
+ {
+ PlatformID platformID = Environment.OSVersion.Platform;
+ if ((int)platformID == 4 || (int)platformID == 128)
+ return RuntimeOS.Unix;
+
+ if ((int)platformID == 3)
+ return RuntimeOS.WindowsCE;
+
+ if (platformID == PlatformID.Win32Windows)
+ return RuntimeOS.Windows;
+
+ if (platformID == PlatformID.Win32NT)
+ return RuntimeOS.WindowsNT;
+
+ return RuntimeOS.Unknown;
+ }
+
+ private static void FindCompatibleFrameworks()
+ {
+ _currentFrameworkCompatibleWith[GetCurrentRuntimeFramework()] = true;
+ _currentFrameworkCompatibleWith[RuntimeFramework.Any] = true;
+ }
+
+ private static void FindCompatibleOSes()
+ {
+ _currentOSCompatibleWith[GetCurrentRuntimeOS()] = true;
+ _currentOSCompatibleWith[RuntimeOS.Any] = true;
+ }
+ }
+}
diff --git a/src/NLog/Internal/PropertyHelper.cs b/src/NLog/Internal/PropertyHelper.cs
new file mode 100644
index 0000000..a167649
--- /dev/null
+++ b/src/NLog/Internal/PropertyHelper.cs
@@ -0,0 +1,392 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Globalization;
+using System.Collections.Specialized;
+using System.Xml;
+
+using NLog.Internal;
+using NLog.Config;
+using System.ComponentModel;
+
+namespace NLog.Internal
+{
+ internal sealed class PropertyHelper
+ {
+ private static TypeToPropertyInfoDictionaryAssociation _parameterInfoCache = new TypeToPropertyInfoDictionaryAssociation();
+
+ private PropertyHelper(){}
+
+ public static string ExpandVariables(string input, NameValueCollection variables)
+ {
+ if (variables == null || variables.Count == 0)
+ return input;
+
+ string output = input;
+
+ // TODO - make this case-insensitive, will probably require a different
+ // approach
+
+ foreach (string s in variables.Keys)
+ {
+ output = output.Replace("${" + s + "}", variables[s]);
+ }
+
+ return output;
+ }
+
+ private static object GetEnumValue(Type enumType, string value)
+ {
+ if (enumType.IsDefined(typeof(FlagsAttribute), false))
+ {
+ ulong union = 0;
+
+ foreach (string v in value.Split(','))
+ {
+ FieldInfo enumField = enumType.GetField(v.Trim(), BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Public);
+ union |= Convert.ToUInt64(enumField.GetValue(null));
+ }
+ object retval = Convert.ChangeType(union, Enum.GetUnderlyingType(enumType), CultureInfo.InvariantCulture);
+ return retval;
+ }
+ else
+ {
+ FieldInfo enumField = enumType.GetField(value, BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Public);
+ return enumField.GetValue(null);
+ }
+ }
+
+ public static bool SetPropertyFromElement(object o, XmlElement el, NameValueCollection variables)
+ {
+ if (AddArrayItemFromElement(o, el, variables))
+ return true;
+
+ if (SetLayoutFromElement(o, el, variables))
+ return true;
+
+ return SetPropertyFromString(o, el.LocalName, el.InnerText, variables);
+ }
+
+ public static bool SetPropertyFromString(object o, string name, string value0, NameValueCollection variables)
+ {
+ string value = ExpandVariables(value0, variables);
+
+ InternalLogger.Debug("Setting '{0}.{1}' to '{2}'", o.GetType().Name, name, value);
+
+ try
+ {
+ PropertyInfo propInfo = GetPropertyInfo(o, name);
+ if (propInfo == null)
+ {
+ throw new NotSupportedException("Parameter " + name + " not supported on " + o.GetType().Name);
+ }
+
+ if (propInfo.IsDefined(typeof(ArrayParameterAttribute), false))
+ {
+ throw new NotSupportedException("Parameter " + name + " of " + o.GetType().Name + " is an array and cannot be assigned a scalar value.");
+ }
+
+ object newValue;
+
+ if (propInfo.PropertyType.IsEnum)
+ {
+ newValue = GetEnumValue(propInfo.PropertyType, value);
+ }
+ else
+ {
+ newValue = Convert.ChangeType(value, propInfo.PropertyType, CultureInfo.InvariantCulture);
+ }
+ propInfo.SetValue(o, newValue, null);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error(ex.ToString());
+ return false;
+ }
+ }
+
+ public static bool AddArrayItemFromElement(object o, XmlElement el, NameValueCollection variables)
+ {
+ string name = el.Name;
+ if (!IsArrayProperty(o.GetType(), name))
+ return false;
+ PropertyInfo propInfo = GetPropertyInfo(o, name);
+ if (propInfo == null)
+ throw new NotSupportedException("Parameter " + name + " not supported on " + o.GetType().Name);
+
+ IList propertyValue = (IList)propInfo.GetValue(o, null);
+ Type elementType = GetArrayItemType(propInfo);
+ object arrayItem = FactoryHelper.CreateInstance(elementType);
+ ConfigureObjectFromAttributes(arrayItem, el.Attributes, variables, true);
+ ConfigureObjectFromElement(arrayItem, el, variables);
+ propertyValue.Add(arrayItem);
+ return true;
+ }
+
+ internal static PropertyInfo GetPropertyInfo(object o, string propertyName)
+ {
+ PropertyInfo propInfo = o.GetType().GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
+ if (propInfo != null)
+ return propInfo;
+
+ lock(_parameterInfoCache)
+ {
+ Type targetType = o.GetType();
+ PropertyInfoDictionary cache = _parameterInfoCache[targetType];
+ if (cache == null)
+ {
+ cache = BuildPropertyInfoDictionary(targetType);
+ _parameterInfoCache[targetType] = cache;
+ }
+ return cache[propertyName.ToLower()];
+ }
+ }
+
+ private static PropertyInfo GetPropertyInfo(Type targetType, string propertyName)
+ {
+ if (propertyName != "")
+ {
+ PropertyInfo propInfo = targetType.GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
+ if (propInfo != null)
+ return propInfo;
+ }
+
+ lock(_parameterInfoCache)
+ {
+ PropertyInfoDictionary cache = _parameterInfoCache[targetType];
+ if (cache == null)
+ {
+ cache = BuildPropertyInfoDictionary(targetType);
+ _parameterInfoCache[targetType] = cache;
+ }
+ return cache[propertyName.ToLower()];
+ }
+ }
+
+ private static PropertyInfoDictionary BuildPropertyInfoDictionary(Type t)
+ {
+ PropertyInfoDictionary retVal = new PropertyInfoDictionary();
+ foreach (PropertyInfo propInfo in t.GetProperties())
+ {
+ if (propInfo.IsDefined(typeof(ArrayParameterAttribute), false))
+ {
+ ArrayParameterAttribute[]attributes = (ArrayParameterAttribute[])propInfo.GetCustomAttributes(typeof(ArrayParameterAttribute), false);
+
+ retVal[attributes[0].ElementName.ToLower()] = propInfo;
+ }
+ else
+ {
+ retVal[propInfo.Name.ToLower()] = propInfo;
+ }
+ if (propInfo.IsDefined(typeof(DefaultParameterAttribute), false))
+ retVal[""] = propInfo;
+ }
+ return retVal;
+ }
+
+ private static Type GetArrayItemType(PropertyInfo propInfo)
+ {
+ if (propInfo.IsDefined(typeof(ArrayParameterAttribute), false))
+ {
+ ArrayParameterAttribute[]attributes = (ArrayParameterAttribute[])propInfo.GetCustomAttributes(typeof(ArrayParameterAttribute), false);
+
+ return attributes[0].ItemType;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public static bool IsArrayProperty(Type t, string name)
+ {
+ PropertyInfo propInfo = GetPropertyInfo(t, name);
+ if (propInfo == null)
+ throw new NotSupportedException("Parameter " + name + " not supported on " + t.Name);
+
+ if (!propInfo.IsDefined(typeof(ArrayParameterAttribute), false))
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ public static bool IsLayoutProperty(Type t, string name)
+ {
+ PropertyInfo propInfo = GetPropertyInfo(t, name);
+ if (propInfo == null)
+ throw new NotSupportedException("Parameter " + name + " not supported on " + t.Name);
+
+ if (typeof(ILayout).IsAssignableFrom(propInfo.PropertyType))
+ return true;
+
+ if (0 == String.Compare(name, "layout", true) && typeof(TargetWithLayout).IsAssignableFrom(propInfo.DeclaringType))
+ return true;
+
+ return false;
+ }
+
+ public static bool EqualsCI(string p1, string p2)
+ {
+ return String.Compare(p1, p2, true) == 0;
+ }
+
+ public static string GetCaseInsensitiveAttribute(XmlElement element, string name, NameValueCollection variables)
+ {
+ // first try a case-sensitive match
+ string s = element.GetAttribute(name);
+ if (s != null && s != "")
+ return PropertyHelper.ExpandVariables(s, variables);
+
+ // then look through all attributes and do a case-insensitive compare
+ // this isn't very fast, but we don't need ultra speed here
+
+ foreach (XmlAttribute a in element.Attributes)
+ {
+ if (EqualsCI(a.LocalName, name))
+ return PropertyHelper.ExpandVariables(a.Value, variables);
+ }
+
+ return null;
+ }
+
+ public static bool HasCaseInsensitiveAttribute(XmlElement element, string name)
+ {
+ // first try a case-sensitive match
+ if (element.HasAttribute(name))
+ return true;
+
+ // then look through all attributes and do a case-insensitive compare
+ // this isn't very fast, but we don't need ultra speed here because usually we have about
+ // 3 attributes per element
+
+ foreach (XmlAttribute a in element.Attributes)
+ {
+ if (EqualsCI(a.LocalName, name))
+ return true;
+ }
+
+ return false;
+ }
+
+ public static bool SetLayoutFromElement(object o, XmlElement el, NameValueCollection variables)
+ {
+ string name = el.LocalName;
+ if (!IsLayoutProperty(o.GetType(), name))
+ return false;
+
+ PropertyInfo targetPropertyInfo = o.GetType().GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase);
+
+ if (targetPropertyInfo != null && typeof(ILayout).IsAssignableFrom(targetPropertyInfo.PropertyType))
+ {
+ ILayout layout = LayoutFactory.CreateLayout(GetCaseInsensitiveAttribute(el, "type", variables));
+ ConfigureObjectFromAttributes(layout, el.Attributes, variables, true);
+ ConfigureObjectFromElement(layout, el, variables);
+ targetPropertyInfo.SetValue(o, layout, null);
+ return true;
+ }
+
+ if (name == "layout" && (o is TargetWithLayout))
+ {
+ if (HasCaseInsensitiveAttribute(el, "type"))
+ {
+ ILayout layout = LayoutFactory.CreateLayout(GetCaseInsensitiveAttribute(el, "type", variables));
+ ConfigureObjectFromAttributes(layout, el.Attributes, variables, true);
+ ConfigureObjectFromElement(layout, el, variables);
+ ((TargetWithLayout)o).CompiledLayout = layout;
+ }
+ else
+ {
+ ((TargetWithLayout)o).Layout = el.InnerText;
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ public static void ConfigureObjectFromAttributes(object targetObject, XmlAttributeCollection attrs, NameValueCollection variables, bool ignoreType)
+ {
+ foreach (XmlAttribute attrib in attrs)
+ {
+ string childName = attrib.LocalName;
+ string childValue = attrib.InnerText;
+
+ if (ignoreType && 0 == String.Compare(childName, "type", true))
+ continue;
+
+ PropertyHelper.SetPropertyFromString(targetObject, childName, childValue, variables);
+ }
+ }
+
+ public static void ConfigureObjectFromElement(object targetObject, XmlElement el, NameValueCollection variables)
+ {
+ foreach (XmlElement el2 in GetChildElements(el))
+ {
+ SetPropertyFromElement(targetObject, el2, variables);
+ }
+ }
+
+ internal static XmlNode[] GetChildElements(XmlElement element)
+ {
+ ArrayList list = new ArrayList();
+ foreach (XmlNode n in element.ChildNodes)
+ {
+ if (n is XmlElement)
+ list.Add(n);
+ }
+ return (XmlElement[])list.ToArray(typeof(XmlElement));
+ }
+
+ internal static XmlNode[] GetChildElements(XmlElement element, string localName)
+ {
+ ArrayList list = new ArrayList();
+ foreach (XmlNode n in element.ChildNodes)
+ {
+ if (0 != String.Compare(localName, n.LocalName, true))
+ continue;
+
+ if (n is XmlElement)
+ list.Add(n);
+ }
+ return (XmlElement[])list.ToArray(typeof(XmlElement));
+ }
+ }
+}
diff --git a/src/NLog/Internal/PropertyInfoDictionary.cs b/src/NLog/Internal/PropertyInfoDictionary.cs
new file mode 100644
index 0000000..3601c19
--- /dev/null
+++ b/src/NLog/Internal/PropertyInfoDictionary.cs
@@ -0,0 +1,164 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+using NLog.Config;
+
+namespace NLog.Internal
+{
+ // CLOVER:OFF
+
+ /// <summary>
+ /// A dictionary with keys of type string and values of type PropertyInfo
+ /// </summary>
+ internal class PropertyInfoDictionary: System.Collections.DictionaryBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the PropertyInfoDictionary class
+ /// </summary>
+ public PropertyInfoDictionary()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Gets or sets the PropertyInfo associated with the given string
+ /// </summary>
+ /// <param name="key">
+ /// The string whose value to get or set.
+ /// </param>
+ public virtual PropertyInfo this[string key]
+ {
+ get { return (PropertyInfo)this.Dictionary[key]; }
+ set { this.Dictionary[key] = value; }
+ }
+
+ /// <summary>
+ /// Adds an element with the specified key and value to this PropertyInfoDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to add.
+ /// </param>
+ /// <param name="value">
+ /// The PropertyInfo value of the element to add.
+ /// </param>
+ public virtual void Add(string key, PropertyInfo value)
+ {
+ this.Dictionary.Add(key, value);
+ }
+
+ /// <summary>
+ /// Determines whether this PropertyInfoDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this PropertyInfoDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this PropertyInfoDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool Contains(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this PropertyInfoDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this PropertyInfoDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this PropertyInfoDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsKey(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this PropertyInfoDictionary contains a specific value.
+ /// </summary>
+ /// <param name="value">
+ /// The PropertyInfo value to locate in this PropertyInfoDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this PropertyInfoDictionary contains an element with the specified value;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsValue(PropertyInfo value)
+ {
+ foreach (PropertyInfo item in this.Dictionary.Values)
+ {
+ if (item == value)
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Removes the element with the specified key from this PropertyInfoDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to remove.
+ /// </param>
+ public virtual void Remove(string key)
+ {
+ this.Dictionary.Remove(key);
+ }
+
+ /// <summary>
+ /// Gets a collection containing the keys in this PropertyInfoDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Keys
+ {
+ get { return this.Dictionary.Keys; }
+ }
+
+ /// <summary>
+ /// Gets a collection containing the values in this PropertyInfoDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Values
+ {
+ get { return this.Dictionary.Values; }
+ }
+ }
+}
diff --git a/src/NLog/Internal/StringCollection.cs b/src/NLog/Internal/StringCollection.cs
new file mode 100644
index 0000000..a46dae5
--- /dev/null
+++ b/src/NLog/Internal/StringCollection.cs
@@ -0,0 +1,231 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if NETCF
+
+// a substitute for the missing .NET CF Class
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace System.Collections.Specialized
+{
+ /// <summary>
+ /// A collection of elements of type String
+ /// </summary>
+ internal class StringCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the StringCollection class.
+ /// </summary>
+ public StringCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the StringCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new StringCollection.
+ /// </param>
+ public StringCollection(String[]items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the StringCollection class, containing elements
+ /// copied from another instance of StringCollection
+ /// </summary>
+ /// <param name="items">
+ /// The StringCollection whose elements are to be added to the new StringCollection.
+ /// </param>
+ public StringCollection(StringCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this StringCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this StringCollection.
+ /// </param>
+ public virtual void AddRange(String[]items)
+ {
+ foreach (String item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another StringCollection to the end of this StringCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The StringCollection whose elements are to be added to the end of this StringCollection.
+ /// </param>
+ public virtual void AddRange(StringCollection items)
+ {
+ foreach (String item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type String to the end of this StringCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The String to be added to the end of this StringCollection.
+ /// </param>
+ public virtual void Add(String value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic String value is in this StringCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The String value to locate in this StringCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this StringCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(String value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this StringCollection
+ /// </summary>
+ /// <param name="value">
+ /// The String value to locate in the StringCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(String value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the StringCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the String is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The String to insert.
+ /// </param>
+ public virtual void Insert(int index, String value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the String at the given index in this StringCollection.
+ /// </summary>
+ public virtual String this[int index]
+ {
+ get { return (String)this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific String from this StringCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The String value to remove from this StringCollection.
+ /// </param>
+ public virtual void Remove(String value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by StringCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ public Enumerator(StringCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ public String Current
+ {
+ get { return (String)(this.wrapped.Current); }
+ }
+
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (String)(this.wrapped.Current); }
+ }
+
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this StringCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual StringCollection.Enumerator GetEnumerator()
+ {
+ return new StringCollection.Enumerator(this);
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Internal/StringDictionary.cs b/src/NLog/Internal/StringDictionary.cs
new file mode 100644
index 0000000..1db264a
--- /dev/null
+++ b/src/NLog/Internal/StringDictionary.cs
@@ -0,0 +1,164 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if NETCF_1_0
+
+using System;
+using System.Collections;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+namespace System.Collections.Specialized
+{
+ /// <summary>
+ /// A dictionary with keys of type string and values of type String
+ /// </summary>
+ internal class StringDictionary: System.Collections.DictionaryBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the StringDictionary class
+ /// </summary>
+ public StringDictionary()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Gets or sets the String associated with the given string
+ /// </summary>
+ /// <param name="key">
+ /// The string whose value to get or set.
+ /// </param>
+ public virtual String this[string key]
+ {
+ get { return (String)this.Dictionary[key]; }
+ set { this.Dictionary[key] = value; }
+ }
+
+ /// <summary>
+ /// Adds an element with the specified key and value to this StringDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to add.
+ /// </param>
+ /// <param name="value">
+ /// The String value of the element to add.
+ /// </param>
+ public virtual void Add(string key, String value)
+ {
+ this.Dictionary.Add(key, value);
+ }
+
+ /// <summary>
+ /// Determines whether this StringDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this StringDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this StringDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool Contains(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this StringDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this StringDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this StringDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsKey(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this StringDictionary contains a specific value.
+ /// </summary>
+ /// <param name="value">
+ /// The String value to locate in this StringDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this StringDictionary contains an element with the specified value;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsValue(String value)
+ {
+ foreach (String item in this.Dictionary.Values)
+ {
+ if (item == value)
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Removes the element with the specified key from this StringDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to remove.
+ /// </param>
+ public virtual void Remove(string key)
+ {
+ this.Dictionary.Remove(key);
+ }
+
+ /// <summary>
+ /// Gets a collection containing the keys in this StringDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Keys
+ {
+ get { return this.Dictionary.Keys; }
+ }
+
+ /// <summary>
+ /// Gets a collection containing the values in this StringDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Values
+ {
+ get { return this.Dictionary.Values; }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Internal/TargetDictionary.cs b/src/NLog/Internal/TargetDictionary.cs
new file mode 100644
index 0000000..805d17b
--- /dev/null
+++ b/src/NLog/Internal/TargetDictionary.cs
@@ -0,0 +1,165 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+using NLog.Config;
+using NLog.Targets;
+
+namespace NLog.Internal
+{
+ // CLOVER:OFF
+
+ /// <summary>
+ /// A dictionary with keys of type string and values of type Target
+ /// </summary>
+ internal class TargetDictionary: System.Collections.DictionaryBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the TargetDictionary class
+ /// </summary>
+ public TargetDictionary()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Gets or sets the Target associated with the given string
+ /// </summary>
+ /// <param name="key">
+ /// The string whose value to get or set.
+ /// </param>
+ public virtual Target this[string key]
+ {
+ get { return (Target)this.Dictionary[key]; }
+ set { this.Dictionary[key] = value; }
+ }
+
+ /// <summary>
+ /// Adds an element with the specified key and value to this TargetDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to add.
+ /// </param>
+ /// <param name="value">
+ /// The Target value of the element to add.
+ /// </param>
+ public virtual void Add(string key, Target value)
+ {
+ this.Dictionary.Add(key, value);
+ }
+
+ /// <summary>
+ /// Determines whether this TargetDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this TargetDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this TargetDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool Contains(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this TargetDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this TargetDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this TargetDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsKey(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this TargetDictionary contains a specific value.
+ /// </summary>
+ /// <param name="value">
+ /// The Target value to locate in this TargetDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this TargetDictionary contains an element with the specified value;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsValue(Target value)
+ {
+ foreach (Target item in this.Dictionary.Values)
+ {
+ if (item == value)
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Removes the element with the specified key from this TargetDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to remove.
+ /// </param>
+ public virtual void Remove(string key)
+ {
+ this.Dictionary.Remove(key);
+ }
+
+ /// <summary>
+ /// Gets a collection containing the keys in this TargetDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Keys
+ {
+ get { return this.Dictionary.Keys; }
+ }
+
+ /// <summary>
+ /// Gets a collection containing the values in this TargetDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Values
+ {
+ get { return this.Dictionary.Values; }
+ }
+ }
+}
diff --git a/src/NLog/Internal/TargetWithFilterChain.cs b/src/NLog/Internal/TargetWithFilterChain.cs
new file mode 100644
index 0000000..1069193
--- /dev/null
+++ b/src/NLog/Internal/TargetWithFilterChain.cs
@@ -0,0 +1,105 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Text;
+
+using NLog.Targets;
+using NLog.Filters;
+
+namespace NLog.Internal
+{
+ internal class TargetWithFilterChain
+ {
+ private Target _target;
+ private FilterCollection _filterChain;
+ private TargetWithFilterChain _next;
+ private int _needsStackTrace = 0;
+
+ public TargetWithFilterChain(Target a, FilterCollection filterChain)
+ {
+ _target = a;
+ _filterChain = filterChain;
+ _needsStackTrace = 0;
+ }
+
+ public Target Target
+ {
+ get { return _target; }
+ }
+
+ public int NeedsStackTrace
+ {
+ get { return _needsStackTrace; }
+ set { _needsStackTrace = value; }
+ }
+
+ public FilterCollection FilterChain
+ {
+ get { return _filterChain; }
+ }
+
+ public TargetWithFilterChain Next
+ {
+ get { return _next; }
+ set { _next = value; }
+ }
+
+ public void PrecalculateNeedsStackTrace()
+ {
+ _needsStackTrace = 0;
+
+ for (TargetWithFilterChain awf = this; awf != null; awf = awf.Next)
+ {
+ if (_needsStackTrace >= 2)
+ break;
+ Target app = awf.Target;
+
+ int nst = app.NeedsStackTrace();
+ _needsStackTrace = Math.Max(_needsStackTrace, nst);
+
+ FilterCollection filterChain = awf.FilterChain;
+
+ for (int i = 0; i < filterChain.Count; ++i)
+ {
+ Filter filter = filterChain[i];
+
+ nst = filter.NeedsStackTrace();
+ _needsStackTrace = Math.Max(_needsStackTrace, nst);
+ }
+ }
+
+ }
+ }
+}
diff --git a/src/NLog/Internal/ThreadIDHelper.cs b/src/NLog/Internal/ThreadIDHelper.cs
new file mode 100644
index 0000000..4441dec
--- /dev/null
+++ b/src/NLog/Internal/ThreadIDHelper.cs
@@ -0,0 +1,236 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Globalization;
+using System.Xml;
+using System.IO;
+using System.Text;
+using System.Runtime.InteropServices;
+
+using NLog.Internal;
+using NLog.Config;
+
+namespace NLog.Internal
+{
+ /// <summary>
+ /// Returns details about current process and thread in a portable manner.
+ /// </summary>
+ public abstract class ThreadIDHelper
+ {
+ /// <summary>
+ /// Singleton instance.
+ /// </summary>
+ public readonly static ThreadIDHelper Instance;
+
+ static ThreadIDHelper()
+ {
+#if NETCF
+ Instance = new Win32ThreadIDHelper();
+#else
+ if (PlatformDetector.IsCurrentOSCompatibleWith(RuntimeOS.Windows)
+ || PlatformDetector.IsCurrentOSCompatibleWith(RuntimeOS.WindowsCE)
+ || PlatformDetector.IsCurrentOSCompatibleWith(RuntimeOS.WindowsNT)
+ )
+ {
+ Instance = new Win32ThreadIDHelper();
+ }
+ else
+ {
+ Instance = new PortableThreadIDHelper();
+ }
+#endif
+ }
+
+ /// <summary>
+ /// Returns current unmanaged thread ID.
+ /// </summary>
+ public abstract int CurrentUnmanagedThreadID { get; }
+
+ /// <summary>
+ /// Returns current thread ID.
+ /// </summary>
+ public abstract int CurrentThreadID { get; }
+
+ /// <summary>
+ /// Returns current process ID.
+ /// </summary>
+ public abstract int CurrentProcessID { get; }
+
+ /// <summary>
+ /// Returns current process name.
+ /// </summary>
+ public abstract string CurrentProcessName { get; }
+
+ /// <summary>
+ /// Returns current process name (excluding filename extension, if any).
+ /// </summary>
+ public abstract string CurrentProcessBaseName { get; }
+
+ /// <summary>
+ /// Returns the base directory where process EXE file resides.
+ /// </summary>
+ public abstract string CurrentProcessDirectory { get; }
+ }
+
+#if !NETCF
+ internal class PortableThreadIDHelper : ThreadIDHelper
+ {
+ private int _currentProcessID;
+ private string _currentProcessName;
+ private string _currentProcessBaseName;
+ private string _currentProcessDirectoryName;
+
+ public PortableThreadIDHelper()
+ {
+ _currentProcessID = System.Diagnostics.Process.GetCurrentProcess().Id;
+ _currentProcessName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
+ _currentProcessBaseName = Path.GetFileNameWithoutExtension(_currentProcessName);
+ _currentProcessDirectoryName = Path.GetDirectoryName(_currentProcessName);
+ }
+
+ public override int CurrentThreadID
+ {
+ get {
+#if NET_2_API
+ return System.Threading.Thread.CurrentThread.ManagedThreadId;
+#else
+ return AppDomain.GetCurrentThreadId();
+#endif
+ }
+ }
+
+ public override int CurrentUnmanagedThreadID
+ {
+ get { return CurrentThreadID; }
+ }
+
+ public override int CurrentProcessID
+ {
+ get { return _currentProcessID; }
+ }
+
+ public override string CurrentProcessName
+ {
+ get { return _currentProcessName; }
+ }
+
+ public override string CurrentProcessBaseName
+ {
+ get { return _currentProcessBaseName; }
+ }
+
+ public override string CurrentProcessDirectory
+ {
+ get { return _currentProcessDirectoryName; }
+ }
+ }
+#endif
+
+ internal class Win32ThreadIDHelper : ThreadIDHelper
+ {
+ private static int _currentProcessID;
+ private static string _currentProcessName;
+ private static string _currentProcessBaseName;
+ private static string _currentProcessDirectoryName;
+
+ public Win32ThreadIDHelper()
+ {
+ _currentProcessID = GetCurrentProcessId();
+ StringBuilder sb = new StringBuilder(512);
+ GetModuleFileName(IntPtr.Zero, sb, sb.Capacity);
+ _currentProcessName = sb.ToString();
+ _currentProcessBaseName = Path.GetFileNameWithoutExtension(_currentProcessName);
+ _currentProcessDirectoryName = Path.GetDirectoryName(_currentProcessName);
+ }
+
+#if !NETCF
+ [DllImport("kernel32.dll")]
+ private extern static int GetCurrentThreadId();
+
+ [DllImport("kernel32.dll")]
+ private extern static int GetCurrentProcessId();
+
+ [DllImport("kernel32.dll", SetLastError=true, PreserveSig=true)]
+ private static extern uint GetModuleFileName([In] IntPtr hModule, [Out] StringBuilder lpFilename, [In] [MarshalAs(UnmanagedType.U4)] int nSize);
+#else
+ [DllImport("coredll.dll")]
+ private extern static int GetCurrentThreadId();
+
+ [DllImport("coredll.dll")]
+ private extern static int GetCurrentProcessId();
+
+ [DllImport("coredll.dll", SetLastError=true)]
+ private static extern uint GetModuleFileName([In] IntPtr hModule, [Out] StringBuilder lpFilename, [In] int nSize);
+#endif
+ public override int CurrentUnmanagedThreadID
+ {
+ get { return GetCurrentThreadId(); }
+ }
+
+ public override int CurrentThreadID
+ {
+ get {
+#if NETCF
+ return CurrentUnmanagedThreadID;
+#elif NET_2_API
+ return System.Threading.Thread.CurrentThread.ManagedThreadId;
+#else
+ return AppDomain.GetCurrentThreadId();
+#endif
+ }
+ }
+
+ public override int CurrentProcessID
+ {
+ get { return _currentProcessID; }
+ }
+
+ public override string CurrentProcessName
+ {
+ get { return _currentProcessName; }
+ }
+
+ public override string CurrentProcessBaseName
+ {
+ get { return _currentProcessBaseName; }
+ }
+
+ public override string CurrentProcessDirectory
+ {
+ get { return _currentProcessDirectoryName; }
+ }
+ }
+}
diff --git a/src/NLog/Internal/TypeDictionary.cs b/src/NLog/Internal/TypeDictionary.cs
new file mode 100644
index 0000000..ad85cba
--- /dev/null
+++ b/src/NLog/Internal/TypeDictionary.cs
@@ -0,0 +1,164 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+using NLog.Config;
+
+namespace NLog.Internal
+{
+ // CLOVER:OFF
+
+ /// <summary>
+ /// A dictionary with keys of type string and values of type Type
+ /// </summary>
+ internal class TypeDictionary: System.Collections.DictionaryBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the TypeDictionary class
+ /// </summary>
+ public TypeDictionary()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Gets or sets the Type associated with the given string
+ /// </summary>
+ /// <param name="key">
+ /// The string whose value to get or set.
+ /// </param>
+ public virtual Type this[string key]
+ {
+ get { return (Type)this.Dictionary[key]; }
+ set { this.Dictionary[key] = value; }
+ }
+
+ /// <summary>
+ /// Adds an element with the specified key and value to this TypeDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to add.
+ /// </param>
+ /// <param name="value">
+ /// The Type value of the element to add.
+ /// </param>
+ public virtual void Add(string key, Type value)
+ {
+ this.Dictionary.Add(key, value);
+ }
+
+ /// <summary>
+ /// Determines whether this TypeDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this TypeDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this TypeDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool Contains(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this TypeDictionary contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The string key to locate in this TypeDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this TypeDictionary contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsKey(string key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this TypeDictionary contains a specific value.
+ /// </summary>
+ /// <param name="value">
+ /// The Type value to locate in this TypeDictionary.
+ /// </param>
+ /// <returns>
+ /// true if this TypeDictionary contains an element with the specified value;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsValue(Type value)
+ {
+ foreach (Type item in this.Dictionary.Values)
+ {
+ if (item == value)
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Removes the element with the specified key from this TypeDictionary.
+ /// </summary>
+ /// <param name="key">
+ /// The string key of the element to remove.
+ /// </param>
+ public virtual void Remove(string key)
+ {
+ this.Dictionary.Remove(key);
+ }
+
+ /// <summary>
+ /// Gets a collection containing the keys in this TypeDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Keys
+ {
+ get { return this.Dictionary.Keys; }
+ }
+
+ /// <summary>
+ /// Gets a collection containing the values in this TypeDictionary.
+ /// </summary>
+ public virtual System.Collections.ICollection Values
+ {
+ get { return this.Dictionary.Values; }
+ }
+ }
+}
diff --git a/src/NLog/Internal/TypeToPropertyInfoDictionaryAssociation.cs b/src/NLog/Internal/TypeToPropertyInfoDictionaryAssociation.cs
new file mode 100644
index 0000000..eae8336
--- /dev/null
+++ b/src/NLog/Internal/TypeToPropertyInfoDictionaryAssociation.cs
@@ -0,0 +1,163 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+using NLog.Config;
+
+namespace NLog.Internal
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A dictionary with keys of type Type and values of type PropertyInfoDictionary
+ /// </summary>
+ internal class TypeToPropertyInfoDictionaryAssociation: System.Collections.DictionaryBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the TypeToPropertyInfoDictionaryAssociation class
+ /// </summary>
+ public TypeToPropertyInfoDictionaryAssociation()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Gets or sets the PropertyInfoDictionary associated with the given Type
+ /// </summary>
+ /// <param name="key">
+ /// The Type whose value to get or set.
+ /// </param>
+ public virtual PropertyInfoDictionary this[Type key]
+ {
+ get { return (PropertyInfoDictionary)this.Dictionary[key]; }
+ set { this.Dictionary[key] = value; }
+ }
+
+ /// <summary>
+ /// Adds an element with the specified key and value to this TypeToPropertyInfoDictionaryAssociation.
+ /// </summary>
+ /// <param name="key">
+ /// The Type key of the element to add.
+ /// </param>
+ /// <param name="value">
+ /// The PropertyInfoDictionary value of the element to add.
+ /// </param>
+ public virtual void Add(Type key, PropertyInfoDictionary value)
+ {
+ this.Dictionary.Add(key, value);
+ }
+
+ /// <summary>
+ /// Determines whether this TypeToPropertyInfoDictionaryAssociation contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The Type key to locate in this TypeToPropertyInfoDictionaryAssociation.
+ /// </param>
+ /// <returns>
+ /// true if this TypeToPropertyInfoDictionaryAssociation contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool Contains(Type key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this TypeToPropertyInfoDictionaryAssociation contains a specific key.
+ /// </summary>
+ /// <param name="key">
+ /// The Type key to locate in this TypeToPropertyInfoDictionaryAssociation.
+ /// </param>
+ /// <returns>
+ /// true if this TypeToPropertyInfoDictionaryAssociation contains an element with the specified key;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsKey(Type key)
+ {
+ return this.Dictionary.Contains(key);
+ }
+
+ /// <summary>
+ /// Determines whether this TypeToPropertyInfoDictionaryAssociation contains a specific value.
+ /// </summary>
+ /// <param name="value">
+ /// The PropertyInfoDictionary value to locate in this TypeToPropertyInfoDictionaryAssociation.
+ /// </param>
+ /// <returns>
+ /// true if this TypeToPropertyInfoDictionaryAssociation contains an element with the specified value;
+ /// otherwise, false.
+ /// </returns>
+ public virtual bool ContainsValue(PropertyInfoDictionary value)
+ {
+ foreach (PropertyInfoDictionary item in this.Dictionary.Values)
+ {
+ if (item == value)
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Removes the element with the specified key from this TypeToPropertyInfoDictionaryAssociation.
+ /// </summary>
+ /// <param name="key">
+ /// The Type key of the element to remove.
+ /// </param>
+ public virtual void Remove(Type key)
+ {
+ this.Dictionary.Remove(key);
+ }
+
+ /// <summary>
+ /// Gets a collection containing the keys in this TypeToPropertyInfoDictionaryAssociation.
+ /// </summary>
+ public virtual System.Collections.ICollection Keys
+ {
+ get { return this.Dictionary.Keys; }
+ }
+
+ /// <summary>
+ /// Gets a collection containing the values in this TypeToPropertyInfoDictionaryAssociation.
+ /// </summary>
+ public virtual System.Collections.ICollection Values
+ {
+ get { return this.Dictionary.Values; }
+ }
+ }
+}
diff --git a/src/NLog/Internal/Win32/Win32FileAttributes.cs b/src/NLog/Internal/Win32/Win32FileAttributes.cs
new file mode 100644
index 0000000..60ece45
--- /dev/null
+++ b/src/NLog/Internal/Win32/Win32FileAttributes.cs
@@ -0,0 +1,137 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Reflection;
+using System.Globalization;
+using NLog.Internal;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace NLog.Internal.Win32
+{
+ /// <summary>
+ /// Win32 file attributes
+ /// </summary>
+ /// <remarks>
+ /// For more information see <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/createfile.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/createfile.asp</a>.
+ /// </remarks>
+ [Flags]
+ public enum Win32FileAttributes : int
+ {
+ /// <summary>
+ /// Read-only
+ /// </summary>
+ Readonly = 0x00000001,
+
+ /// <summary>
+ /// Hidden
+ /// </summary>
+ Hidden = 0x00000002,
+
+ /// <summary>
+ /// System
+ /// </summary>
+ System = 0x00000004,
+
+ /// <summary>
+ /// File should be archived.
+ /// </summary>
+ Archive = 0x00000020,
+
+ /// <summary>
+ /// Device
+ /// </summary>
+ Device = 0x00000040,
+
+ /// <summary>
+ /// Normal
+ /// </summary>
+ Normal = 0x00000080,
+
+ /// <summary>
+ /// File is temporary (should be kept in cache and not
+ /// written to disk if possible)
+ /// </summary>
+ Temporary = 0x00000100,
+
+ /// <summary>
+ /// Sparse file.
+ /// </summary>
+ SparseFile = 0x00000200,
+
+ /// <summary>
+ /// Reparse point.
+ /// </summary>
+ ReparsePoint = 0x00000400,
+
+ /// <summary>
+ /// Compress file contents.
+ /// </summary>
+ Compressed = 0x00000800,
+
+ /// <summary>
+ /// File should not be indexed by the content indexing service.
+ /// </summary>
+ NotContentIndexed = 0x00002000,
+
+ /// <summary>
+ /// Encrypt file.
+ /// </summary>
+ Encrypted = 0x00004000,
+
+ /// <summary>
+ /// The system writes through any intermediate cache and goes directly to disk.
+ /// </summary>
+ WriteThrough = unchecked((int)0x80000000),
+
+ /// <summary>
+ /// The system opens a file with no system caching
+ /// </summary>
+ NoBuffering = 0x20000000,
+
+ /// <summary>
+ /// Delete file after it is closed.
+ /// </summary>
+ DeleteOnClose = 0x04000000,
+
+ /// <summary>
+ /// A file is accessed according to POSIX rules.
+ /// </summary>
+ PosixSemantics = 0x01000000,
+ };
+}
+
+#endif
diff --git a/src/NLog/Internal/Win32/Win32FileHelper.cs b/src/NLog/Internal/Win32/Win32FileHelper.cs
new file mode 100644
index 0000000..c6c5942
--- /dev/null
+++ b/src/NLog/Internal/Win32/Win32FileHelper.cs
@@ -0,0 +1,101 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Reflection;
+using System.Globalization;
+using NLog.Internal;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace NLog.Internal.Win32
+{
+ internal class Win32FileHelper
+ {
+ public const int FILE_SHARE_READ = 1;
+ public const int FILE_SHARE_WRITE = 2;
+ public const int FILE_SHARE_DELETE = 4;
+
+ [Flags]
+ public enum FileAccess : uint
+ {
+ GenericRead = 0x80000000,
+ GenericWrite = 0x40000000,
+ GenericExecute = 0x20000000,
+ GenericAll = 0x10000000,
+ }
+
+ public enum CreationDisposition : uint
+ {
+ New = 1,
+ CreateAlways = 2,
+ OpenExisting = 3,
+ OpenAlways = 4,
+ TruncateExisting = 5,
+ }
+
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr CreateFile(
+ string lpFileName,
+ FileAccess dwDesiredAccess,
+ int dwShareMode,
+ IntPtr lpSecurityAttributes,
+ CreationDisposition dwCreationDisposition,
+ Win32FileAttributes dwFlagsAndAttributes,
+ IntPtr hTemplateFile);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern bool GetFileInformationByHandle(IntPtr hFile,
+ out BY_HANDLE_FILE_INFORMATION lpFileInformation);
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct BY_HANDLE_FILE_INFORMATION
+ {
+ public uint dwFileAttributes;
+ public long ftCreationTime;
+ public long ftLastAccessTime;
+ public long ftLastWriteTime;
+ public uint dwVolumeSerialNumber;
+ public uint nFileSizeHigh;
+ public uint nFileSizeLow;
+ public uint nNumberOfLinks;
+ public uint nFileIndexHigh;
+ public uint nFileIndexLow;
+ };
+ }
+}
+
+#endif
diff --git a/src/NLog/Layout.cs b/src/NLog/Layout.cs
new file mode 100644
index 0000000..eb6a5dc
--- /dev/null
+++ b/src/NLog/Layout.cs
@@ -0,0 +1,319 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+
+using NLog.Internal;
+using NLog.LayoutRenderers;
+
+using System.Threading;
+using NLog.Config;
+using System.IO;
+using System.Reflection;
+
+namespace NLog
+{
+ /// <summary>
+ /// Represents a string with embedded placeholders that can render contextual information.
+ /// </summary>
+ [Layout("SimpleLayout")]
+ public sealed class Layout : ILayout
+ {
+ /// <summary>
+ /// Creates a new instance of the <see cref="Layout"/> and sets it to empty string.
+ /// </summary>
+ public Layout()
+ {
+ Text = String.Empty;
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="Layout"/> and sets it to the specified string.
+ /// </summary>
+ /// <param name="txt">The layout string to parse.</param>
+ public Layout(string txt)
+ {
+ Text = txt;
+ }
+
+ internal Layout(LayoutRenderer[] renderers, string text)
+ {
+ SetRenderers(renderers, text);
+ }
+
+ private string _layoutText;
+ private LayoutRenderer[] _renderers;
+ private int _needsStackTrace = 0;
+ private bool _isVolatile = false;
+ private string _fixedText;
+
+ /// <summary>
+ /// The layout text
+ /// </summary>
+ [AcceptsLayout]
+ public string Text
+ {
+ get { return _layoutText; }
+ set {
+ LayoutRenderer[] renderers;
+ string txt;
+
+ renderers = LayoutParser.CompileLayout(
+ new LayoutParser.Tokenizer(value),
+ false,
+ out txt);
+
+ SetRenderers(renderers, txt);
+ }
+ }
+
+ /// <summary>
+ /// Returns true if this layout produces a value that doesn't change for a particular
+ /// AppDomain.
+ /// </summary>
+ public bool IsAppDomainFixed
+ {
+ get { return _fixedText != null; }
+ }
+
+ /// <summary>
+ /// Renders the layout for the specified logging event by invoking layout renderers
+ /// that make up the event.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ /// <returns>The rendered layout.</returns>
+ public string GetFormattedMessage(LogEventInfo logEvent)
+ {
+ if (_fixedText != null)
+ return _fixedText;
+
+ string cachedValue = logEvent.GetCachedLayoutValue(this);
+ if (cachedValue != null)
+ return cachedValue;
+
+ int size = 0;
+
+ for (int i = 0; i < _renderers.Length; ++i)
+ {
+ LayoutRenderer app = _renderers[i];
+ try
+ {
+ int ebs = app.GetEstimatedBufferSize(logEvent);
+ size += ebs;
+ }
+ catch (Exception ex)
+ {
+ if (InternalLogger.IsWarnEnabled)
+ {
+ InternalLogger.Warn("Exception in {0}.GetEstimatedBufferSize(): {1}.", app.GetType().FullName, ex);
+ }
+ }
+ }
+ StringBuilder builder = new StringBuilder(size);
+
+ for (int i = 0; i < _renderers.Length; ++i)
+ {
+ LayoutRenderer app = _renderers[i];
+ try
+ {
+ app.Append(builder, logEvent);
+ }
+ catch (Exception ex)
+ {
+ if (InternalLogger.IsWarnEnabled)
+ {
+ InternalLogger.Warn("Exception in {0}.Append(): {1}.", app.GetType().FullName, ex);
+ }
+ }
+ }
+
+ string value = builder.ToString();
+ logEvent.AddCachedLayoutValue(this, value);
+ return value;
+ }
+
+ /// <summary>
+ /// Returns the value indicating whether a stack trace and/or the source file
+ /// information should be gathered during layout processing.
+ /// </summary>
+ /// <returns>0 - don't include stack trace<br/>1 - include stack trace without source file information<br/>2 - include full stack trace</returns>
+ public int NeedsStackTrace()
+ {
+ return _needsStackTrace;
+ }
+
+ /// <summary>
+ /// Returns the value indicating whether this layout includes any volatile
+ /// layout renderers.
+ /// </summary>
+ /// <returns><see langword="true" /> when the layout includes at least
+ /// one volatile renderer, <see langword="false"/> otherwise.</returns>
+ /// <remarks>
+ /// Volatile layout renderers are dependent on information not contained
+ /// in <see cref="LogEventInfo"/> (such as thread-specific data, MDC data, NDC data).
+ /// </remarks>
+ public bool IsVolatile()
+ {
+ return _isVolatile;
+ }
+
+ /// <summary>
+ /// A collection of <see cref="LayoutRenderer"/> objects that make up this layout.
+ /// </summary>
+ public LayoutRenderer[] Renderers
+ {
+ get { return _renderers; }
+ }
+
+ internal void SetRenderers(LayoutRenderer[] renderers, string text)
+ {
+ _renderers = renderers;
+ if (_renderers.Length == 1 && _renderers[0] is LiteralLayoutRenderer)
+ _fixedText = ((LiteralLayoutRenderer)(_renderers[0])).Text;
+ else
+ _fixedText = null;
+
+ _layoutText = text;
+
+ _isVolatile = false;
+ _needsStackTrace = 0;
+
+ foreach (LayoutRenderer lr in renderers)
+ {
+ int nst = lr.NeedsStackTrace();
+ if (nst > _needsStackTrace)
+ _needsStackTrace = nst;
+ if (lr.IsVolatile())
+ _isVolatile = true;
+ }
+ }
+
+ /// <summary>
+ /// Precalculates the layout for the specified log event and stores the result
+ /// in per-log event cache.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ /// <remarks>
+ /// Calling this method enables you to store the log event in a buffer
+ /// and/or potentially evaluate it in another thread even though the
+ /// layout may contain thread-dependent renderer.
+ /// </remarks>
+ public void Precalculate(LogEventInfo logEvent)
+ {
+ //Console.WriteLine("Precalculating {0}", this.Text);
+ GetFormattedMessage(logEvent);
+ }
+
+ /// <summary>
+ /// Escapes the passed text so that it can
+ /// be used literally in all places where
+ /// layout is normally expected without being
+ /// treated as layout.
+ /// </summary>
+ /// <param name="text">The text to be escaped.</param>
+ /// <returns>The escaped text.</returns>
+ /// <remarks>
+ /// Escaping is done by replacing all occurences of
+ /// '${' with '${literal:text=${}'
+ /// </remarks>
+ public static string Escape(string text)
+ {
+ return text.Replace("${", "${literal:text=${}");
+ }
+
+ /// <summary>
+ /// Evaluates the specified text by expadinging all layout renderers.
+ /// </summary>
+ /// <param name="text">The text to be evaluated.</param>
+ /// <param name="logEvent">Log event to be used for evaluation</param>
+ /// <returns>The input text with all occurences of ${} replaced with
+ /// values provided by the appropriate layout renderers.</returns>
+ public static string Evaluate(string text, LogEventInfo logEvent)
+ {
+ Layout l = new Layout(text);
+ return l.GetFormattedMessage(logEvent);
+ }
+
+ /// <summary>
+ /// Evaluates the specified text by expadinging all layout renderers
+ /// in new <see cref="LogEventInfo" /> context.
+ /// </summary>
+ /// <param name="text">The text to be evaluated.</param>
+ /// <returns>The input text with all occurences of ${} replaced with
+ /// values provided by the appropriate layout renderers.</returns>
+ public static string Evaluate(string text)
+ {
+ return Evaluate(text, LogEventInfo.CreateNullEvent());
+ }
+
+ /// <summary>
+ /// Initializes the layout.
+ /// </summary>
+ public void Initialize()
+ {
+ foreach (LayoutRenderer lr in Renderers)
+ {
+ lr.Initialize();
+ }
+ }
+
+ /// <summary>
+ /// Closes the layout;
+ /// </summary>
+ public void Close()
+ {
+ }
+
+ /// <summary>
+ /// Add this layout and all sub-layouts to the specified collection..
+ /// </summary>
+ /// <param name="layouts">The collection of layouts.</param>
+ public void PopulateLayouts(LayoutCollection layouts)
+ {
+ layouts.Add(this);
+ }
+
+ /// <summary>
+ /// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
+ /// </returns>
+ public override string ToString()
+ {
+ return Text;
+ }
+ }
+}
diff --git a/src/NLog/LayoutAttribute.cs b/src/NLog/LayoutAttribute.cs
new file mode 100644
index 0000000..17e1457
--- /dev/null
+++ b/src/NLog/LayoutAttribute.cs
@@ -0,0 +1,64 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog
+{
+ /// <summary>
+ /// Marks class as a layout renderer and assigns a format string to it.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class)]
+ public sealed class LayoutAttribute: Attribute
+ {
+ private string _name;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="LayoutAttribute"/>
+ /// and assigns the <see cref="Name"/> to the specified value.
+ /// </summary>
+ /// <param name="name">layout name</param>
+ public LayoutAttribute(string name)
+ {
+ _name = name;
+ }
+
+ /// <summary>
+ /// The layout name.
+ /// </summary>
+ public string Name
+ {
+ get { return _name; }
+ }
+ }
+}
diff --git a/src/NLog/LayoutCollection.cs b/src/NLog/LayoutCollection.cs
new file mode 100644
index 0000000..40959d1
--- /dev/null
+++ b/src/NLog/LayoutCollection.cs
@@ -0,0 +1,243 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace NLog
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A collection of elements of type ILayout
+ /// </summary>
+ public class LayoutCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the LayoutCollection class.
+ /// </summary>
+ public LayoutCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the LayoutCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new LayoutCollection.
+ /// </param>
+ public LayoutCollection(ILayout[]items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the LayoutCollection class, containing elements
+ /// copied from another instance of LayoutCollection
+ /// </summary>
+ /// <param name="items">
+ /// The LayoutCollection whose elements are to be added to the new LayoutCollection.
+ /// </param>
+ public LayoutCollection(LayoutCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this LayoutCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this LayoutCollection.
+ /// </param>
+ public virtual void AddRange(ILayout[]items)
+ {
+ foreach (ILayout item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another LayoutCollection to the end of this LayoutCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The LayoutCollection whose elements are to be added to the end of this LayoutCollection.
+ /// </param>
+ public virtual void AddRange(LayoutCollection items)
+ {
+ foreach (ILayout item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type ILayout to the end of this LayoutCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The ILayout to be added to the end of this LayoutCollection.
+ /// </param>
+ public virtual void Add(ILayout value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic ILayout value is in this LayoutCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The ILayout value to locate in this LayoutCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this LayoutCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(ILayout value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this LayoutCollection
+ /// </summary>
+ /// <param name="value">
+ /// The ILayout value to locate in the LayoutCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(ILayout value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the LayoutCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the ILayout is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The ILayout to insert.
+ /// </param>
+ public virtual void Insert(int index, ILayout value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the ILayout at the given index in this LayoutCollection.
+ /// </summary>
+ public virtual ILayout this[int index]
+ {
+ get { return (ILayout)this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific ILayout from this LayoutCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The ILayout value to remove from this LayoutCollection.
+ /// </param>
+ public virtual void Remove(ILayout value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by LayoutCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(LayoutCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public ILayout Current
+ {
+ get { return (ILayout)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (ILayout)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this LayoutCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual LayoutCollection.Enumerator GetEnumerator()
+ {
+ return new LayoutCollection.Enumerator(this);
+ }
+ }
+}
diff --git a/src/NLog/LayoutFactory.cs b/src/NLog/LayoutFactory.cs
new file mode 100644
index 0000000..cd63267
--- /dev/null
+++ b/src/NLog/LayoutFactory.cs
@@ -0,0 +1,145 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Reflection;
+using System.Globalization;
+
+using NLog.Internal;
+using NLog.Layouts;
+using NLog.Config;
+
+namespace NLog
+{
+ /// <summary>
+ /// A factory for layouts. Creates new layout instances based on their names.
+ /// </summary>
+ public sealed class LayoutFactory
+ {
+ private static TypeDictionary _name2type = new TypeDictionary();
+
+ static LayoutFactory()
+ {
+ foreach (Assembly a in ExtensionUtils.GetExtensionAssemblies())
+ {
+ AddLayoutsFromAssembly(a, "");
+ }
+ }
+
+ private LayoutFactory(){}
+
+ /// <summary>
+ /// Removes all layout information from the factory.
+ /// </summary>
+ public static void Clear()
+ {
+ _name2type.Clear();
+ }
+
+ /// <summary>
+ /// Scans the specified assembly for types marked with <see cref="LayoutAttribute" /> and adds
+ /// them to the factory. Optionally it prepends the specified text to layout names to avoid
+ /// naming collisions.
+ /// </summary>
+ /// <param name="theAssembly">The assembly to be scanned for layouts.</param>
+ /// <param name="prefix">The prefix to be prepended to layout names.</param>
+ public static void AddLayoutsFromAssembly(Assembly theAssembly, string prefix)
+ {
+ try
+ {
+ InternalLogger.Debug("AddLayoutsFromAssembly('{0}')", theAssembly.FullName);
+ foreach (Type t in theAssembly.GetTypes())
+ {
+ LayoutAttribute[]attributes = (LayoutAttribute[])t.GetCustomAttributes(typeof(LayoutAttribute), false);
+ if (attributes != null)
+ {
+ foreach (LayoutAttribute attr in attributes)
+ {
+ if (PlatformDetector.IsSupportedOnCurrentRuntime(t))
+ {
+ AddLayout(prefix + attr.Name, t);
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Failed to add layouts from '" + theAssembly.FullName + "': {0}", ex);
+ }
+ }
+
+ /// <summary>
+ /// Registers the specified layout type to the factory under a specified name.
+ /// </summary>
+ /// <param name="name">The name of the layout (e.g. <code>XML</code>, <code>CSV</code> or <code>HTML</code>)</param>
+ /// <param name="t">The type of the new layout</param>
+ /// <remarks>
+ /// The name specified in the name parameter can then be used
+ /// to reference layouts.
+ /// </remarks>
+ public static void AddLayout(string name, Type t)
+ {
+ InternalLogger.Trace("Registering layout {0} for type '{1}'", name, t.FullName);
+ _name2type[name.ToLower()] = t;
+ }
+
+ /// <summary>
+ /// Creates the layout renderer object based on its layout renderer name and sets its properties from parameters string.
+ /// </summary>
+ /// <param name="name">The name of the layout renderer (e.g. <code>message</code> or <code>aspnet-request</code>)</param>
+ /// <returns>A new instance of the <see cref="ILayout"/> object.</returns>
+ public static ILayout CreateLayout(string name)
+ {
+ Type t = _name2type[name.ToLower()];
+ if (t != null)
+ {
+ ILayout la = FactoryHelper.CreateInstance(t) as ILayout;
+ if (la != null)
+ return la;
+ }
+ throw new ArgumentException("Layout " + name + " not found.");
+ }
+
+ /// <summary>
+ /// Collection of layout types added to the factory.
+ /// </summary>
+ public static ICollection LayoutTypes
+ {
+ get { return _name2type.Values; }
+ }
+ }
+}
diff --git a/src/NLog/LayoutParser.cs b/src/NLog/LayoutParser.cs
new file mode 100644
index 0000000..56d4b0f
--- /dev/null
+++ b/src/NLog/LayoutParser.cs
@@ -0,0 +1,316 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+
+using NLog.Internal;
+using NLog.LayoutRenderers;
+
+using System.Threading;
+using NLog.Config;
+using System.IO;
+using System.Reflection;
+
+namespace NLog
+{
+ internal sealed class LayoutParser
+ {
+ private static string ParseLayoutRendererName(Tokenizer sr)
+ {
+ int ch;
+
+ StringBuilder nameBuf = new StringBuilder();
+ while ((ch = sr.Peek()) != -1)
+ {
+ if (ch == ':' || ch == '}')
+ break;
+ nameBuf.Append((char)ch);
+ sr.Read();
+ }
+
+ return nameBuf.ToString();
+ }
+
+ private static string ParseParameterName(Tokenizer sr)
+ {
+ int ch;
+ int nestLevel = 0;
+
+ StringBuilder nameBuf = new StringBuilder();
+ while ((ch = sr.Peek()) != -1)
+ {
+ if ((ch == '=' || ch == '}' || ch == ':') && nestLevel == 0)
+ break;
+ if (ch == '$')
+ {
+ sr.Read();
+ nameBuf.Append('$');
+ if (sr.Peek() == '{')
+ {
+ nameBuf.Append('{');
+ nestLevel++;
+ sr.Read();
+ }
+ continue;
+ }
+ if (ch == '}')
+ {
+ nestLevel--;
+ }
+ if (ch == '\\')
+ {
+ // skip the backslash
+ sr.Read();
+
+ // append next character
+ nameBuf.Append((char)sr.Read());
+ continue;
+ }
+ nameBuf.Append((char)ch);
+ sr.Read();
+ }
+
+ return nameBuf.ToString();
+ }
+
+ private static string ParseParameterValue(Tokenizer sr)
+ {
+ int ch;
+
+ StringBuilder nameBuf = new StringBuilder();
+ while ((ch = sr.Peek()) != -1)
+ {
+ if (ch == ':' || ch == '}')
+ break;
+ if (ch == '\\')
+ {
+ // skip the backslash
+ sr.Read();
+
+ // append next character
+ nameBuf.Append((char)sr.Read());
+ continue;
+ }
+ nameBuf.Append((char)ch);
+ sr.Read();
+ }
+
+ return nameBuf.ToString();
+ }
+
+ private static LayoutRenderer ParseLayoutRenderer(Tokenizer sr)
+ {
+ int ch;
+
+ ch = sr.Read();
+ if (ch != '{')
+ throw new NLogConfigurationException("'{' expected in layout specification");
+
+ string name = ParseLayoutRendererName(sr);
+ LayoutRenderer lr = LayoutRendererFactory.CreateLayoutRenderer(name, null);
+
+ ch = sr.Read();
+ while (ch != -1 && ch != '}')
+ {
+ string parameterName = ParseParameterName(sr).Trim();
+ if (sr.Peek() == '=')
+ {
+ sr.Read(); // skip the '='
+ PropertyInfo pi = PropertyHelper.GetPropertyInfo(lr, parameterName);
+ if (pi == null)
+ {
+ ParseParameterValue(sr);
+ }
+ else
+ {
+ if (typeof(Layout) == pi.PropertyType)
+ {
+ Layout nestedLayout = new Layout();
+ string txt;
+ LayoutRenderer[] renderers = CompileLayout(sr, true, out txt);
+
+ nestedLayout.SetRenderers(renderers, txt);
+ pi.SetValue(lr, nestedLayout, null);
+ }
+ else
+ {
+ string value = ParseParameterValue(sr);
+ PropertyHelper.SetPropertyFromString(lr, parameterName, value, null);
+ }
+ }
+ }
+ else
+ {
+ // what we've just read is not a parameterName, but a value
+ // assign it to a default property (denoted by empty string)
+
+ PropertyInfo pi = PropertyHelper.GetPropertyInfo(lr, "");
+ if (pi != null)
+ {
+ if (typeof(Layout) == pi.PropertyType)
+ {
+ pi.SetValue(lr, new Layout(parameterName), null);
+ }
+ else
+ {
+ string value = parameterName;
+ PropertyHelper.SetPropertyFromString(lr, pi.Name, value, null);
+ }
+ }
+ else
+ {
+ InternalLogger.Warn("{0} has no default property", lr.GetType().FullName);
+ }
+ }
+ ch = sr.Read();
+ }
+ return lr;
+ }
+
+ internal static LayoutRenderer[] CompileLayout(Tokenizer sr, bool isNested, out string text)
+ {
+ ArrayList result = new ArrayList();
+ StringBuilder literalBuf = new StringBuilder();
+
+ int ch;
+
+ int p0 = sr.Position;
+
+ while ((ch = sr.Peek()) != -1)
+ {
+ if (isNested && (ch == '}' || ch == ':'))
+ {
+ break;
+ }
+ sr.Read();
+
+ if (ch == '$' && sr.Peek() == '{')
+ {
+ if (literalBuf.Length > 0)
+ {
+ result.Add(new LiteralLayoutRenderer(literalBuf.ToString()));
+ literalBuf.Length = 0;
+ }
+
+ LayoutRenderer newLayoutRenderer = ParseLayoutRenderer(sr);
+ if (newLayoutRenderer.IsAppDomainFixed())
+ newLayoutRenderer = ConvertToLiteral(newLayoutRenderer);
+ result.Add(newLayoutRenderer);
+ // layout renderer
+ }
+ else
+ {
+ literalBuf.Append((char)ch);
+ }
+ }
+
+ if (literalBuf.Length > 0)
+ {
+ result.Add(new LiteralLayoutRenderer(literalBuf.ToString()));
+ literalBuf.Length = 0;
+ }
+ int p1 = sr.Position;
+
+ MergeLiterals(result);
+ text = sr.Substring(p0, p1);
+
+ return (LayoutRenderer[])result.ToArray(typeof(LayoutRenderer));
+ }
+
+
+ private static void MergeLiterals(ArrayList list)
+ {
+ for (int i = 0; i + 1 < list.Count;)
+ {
+ LiteralLayoutRenderer lr1 = list[i] as LiteralLayoutRenderer;
+ LiteralLayoutRenderer lr2 = list[i + 1] as LiteralLayoutRenderer;
+ if (lr1 != null && lr2 != null)
+ {
+ lr1.Text += lr2.Text;
+ list.RemoveAt(i + 1);
+ }
+ else
+ {
+ i++;
+ }
+ }
+ }
+
+ private static LayoutRenderer ConvertToLiteral(LayoutRenderer renderer)
+ {
+ StringBuilder sb = new StringBuilder();
+ renderer.Append(sb, LogEventInfo.CreateNullEvent());
+ return new LiteralLayoutRenderer(sb.ToString());
+ }
+
+ internal class Tokenizer
+ {
+ private string _text;
+ private int _pos;
+
+ public Tokenizer(string text)
+ {
+ _text = text;
+ _pos = 0;
+ }
+
+ public int Peek()
+ {
+ if (_pos < _text.Length)
+ return _text[_pos];
+ else
+ return -1;
+ }
+
+ public int Read()
+ {
+ if (_pos < _text.Length)
+ return _text[_pos++];
+ else
+ return -1;
+ }
+
+ public int Position
+ {
+ get { return _pos; }
+ }
+
+ public string Substring(int p0, int p1)
+ {
+ return _text.Substring(p0, p1 - p0);
+ }
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderer.cs b/src/NLog/LayoutRenderer.cs
new file mode 100644
index 0000000..32ed707
--- /dev/null
+++ b/src/NLog/LayoutRenderer.cs
@@ -0,0 +1,273 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Text;
+using System.Globalization;
+
+namespace NLog
+{
+ /// <summary>
+ /// Render environmental information related to logging events.
+ /// </summary>
+ public abstract class LayoutRenderer
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="LayoutRenderer" />
+ /// </summary>
+ protected LayoutRenderer(){}
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal abstract int GetEstimatedBufferSize(LogEventInfo logEvent);
+
+ /// <summary>
+ /// Determines whether stack trace information should be gathered
+ /// during log event processing. By default it calls <see cref="NLog.Layout.NeedsStackTrace" /> on
+ /// <see cref="TargetWithLayout.CompiledLayout" />.
+ /// </summary>
+ /// <returns>0 - don't include stack trace<br/>1 - include stack trace without source file information<br/>2 - include full stack trace</returns>
+ protected internal virtual int NeedsStackTrace()
+ {
+ return 0;
+ }
+
+ /// <summary>
+ /// Determines whether the layout renderer is volatile.
+ /// </summary>
+ /// <returns>A boolean indicating whether the layout renderer is volatile.</returns>
+ /// <remarks>
+ /// Volatile layout renderers are dependent on information not contained
+ /// in <see cref="LogEventInfo"/> (such as thread-specific data, MDC data, NDC data).
+ /// </remarks>
+ protected internal virtual bool IsVolatile()
+ {
+ LayoutRendererAttribute attr = (LayoutRendererAttribute)Attribute.GetCustomAttribute(this.GetType(), typeof(LayoutRendererAttribute));
+ if (attr == null)
+ return false;
+ return !attr.UsingLogEventInfo;
+ }
+
+ /// <summary>
+ /// Renders the specified environmental information and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal abstract void Append(StringBuilder builder, LogEventInfo logEvent);
+
+ private int _padding = 0;
+ private bool _fixedLength = false;
+ private int _absolutePadding = 0;
+ private bool _upperCase = false;
+ private bool _lowerCase = false;
+ private char _padCharacter = ' ';
+ private CultureInfo _cultureInfo = CultureInfo.InvariantCulture;
+
+ /// <summary>
+ /// Padding value.
+ /// </summary>
+ public int Padding
+ {
+ get { return _padding; }
+ set
+ {
+ _padding = value;
+ _absolutePadding = Math.Abs(_padding);
+ }
+ }
+
+ /// <summary>
+ /// The absolute value of the <see cref="Padding"/> property.
+ /// </summary>
+ public int AbsolutePadding
+ {
+ get { return _absolutePadding; }
+ }
+
+ /// <summary>
+ /// The padding character.
+ /// </summary>
+ public char PadCharacter
+ {
+ get { return _padCharacter; }
+ set { _padCharacter = value; }
+ }
+
+ /// <summary>
+ /// Trim the rendered text to the AbsolutePadding value.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool FixedLength
+ {
+ get { return _fixedLength; }
+ set { _fixedLength = value; }
+ }
+
+ /// <summary>
+ /// Render an upper-case string.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool UpperCase
+ {
+ get { return _upperCase; }
+ set { _upperCase = value; }
+ }
+
+ /// <summary>
+ /// Render an upper-case string.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool LowerCase
+ {
+ get { return _lowerCase; }
+ set { _lowerCase = value; }
+ }
+
+ /// <summary>
+ /// The culture name to be used for rendering.
+ /// </summary>
+ /// <example>
+ /// The format for culture names is described in <a href="http://rfc.net/rfc1766.html">RFC 1766</a> and at <a href="http://msdn2.microsoft.com/en-us/library/system.globalization.cultureinfo.cultureinfo.aspx">MSDN</a>.
+ /// Some examples of valid culture names are:
+ /// <ul>
+ /// <li><b>en-US</b> - English (United States)</li>
+ /// <li><b>en-UK</b> - English (United Kingdom)</li>
+ /// <li><b>pl-PL</b> - Polish</li>
+ /// <li><b>ar-SA</b> - Arabic (Saudi Arabia)</li>
+ /// </ul>
+ /// </example>
+ public string Culture
+ {
+ get { return _cultureInfo.Name; }
+ set { _cultureInfo = new CultureInfo(value); }
+ }
+
+ /// <summary>
+ /// The <see cref="System.Globalization.CultureInfo" /> to be used for rendering.
+ /// </summary>
+ public CultureInfo CultureInfo
+ {
+ get { return _cultureInfo; }
+ set { _cultureInfo = value; }
+ }
+
+ /// <summary>
+ /// Determines whether it's necessary to call <see cref="ApplyPadding" />.
+ /// </summary>
+ /// <returns><see langword="true"/> when there's any
+ /// trimming, padding or case conversion necessary,
+ /// <see langword="false"/> otherwise</returns>
+ /// <remarks>
+ /// Should this method return <see langword="true"/>,
+ /// it's necessary to call ApplyPadding on a rendered text,
+ /// otherwise it's not necessary to do so.
+ /// </remarks>
+ protected bool NeedPadding()
+ {
+ return (Padding != 0) || UpperCase || LowerCase;
+ }
+
+
+ /// <summary>
+ /// Post-processes the rendered message by applying padding,
+ /// upper- and lower-case conversion.
+ /// </summary>
+ /// <param name="s">The text to be post-processed.</param>
+ /// <returns>Padded, trimmed, and case-converted string.</returns>
+ protected string ApplyPadding(string s)
+ {
+ if (s == null)
+ s = String.Empty;
+ if (Padding != 0)
+ {
+ if (Padding > 0)
+ {
+ s = s.PadLeft(Padding, PadCharacter);
+ }
+ else
+ {
+ s = s.PadRight(-Padding, PadCharacter);
+ }
+ if (FixedLength && s.Length > AbsolutePadding)
+ {
+ s = s.Substring(0, AbsolutePadding);
+ }
+ }
+ if (UpperCase)
+ {
+ s = s.ToUpper(CultureInfo);
+ }
+ else if (LowerCase)
+ {
+ s = s.ToLower(CultureInfo);
+ }
+ return s;
+ }
+
+ /// <summary>
+ /// Determines whether the value produced by the layout renderer
+ /// is fixed per current app-domain.
+ /// </summary>
+ /// <returns>The boolean value. <c>true</c> makes the value
+ /// of the layout renderer be precalculated and inserted as a literal
+ /// in the resulting layout string.</returns>
+ protected internal virtual bool IsAppDomainFixed()
+ {
+ return false;
+ }
+
+ /// <summary>
+ /// Initializes the layout renderer.
+ /// </summary>
+ public virtual void Initialize()
+ {
+ }
+
+ /// <summary>
+ /// Closes the layout renderer.
+ /// </summary>
+ public virtual void Close()
+ {
+ }
+ }
+}
diff --git a/src/NLog/LayoutRendererAttribute.cs b/src/NLog/LayoutRendererAttribute.cs
new file mode 100644
index 0000000..b93af8b
--- /dev/null
+++ b/src/NLog/LayoutRendererAttribute.cs
@@ -0,0 +1,86 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog
+{
+ /// <summary>
+ /// Marks class as a layout renderer and assigns a format string to it.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class)]
+ public sealed class LayoutRendererAttribute: Attribute
+ {
+ private string _formatString;
+ private bool _ignoresPadding = false;
+ private bool _usingLogEventInfo = false;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="LayoutRendererAttribute"/>
+ /// and assigns the <see cref="FormatString"/> to the specified value.
+ /// </summary>
+ /// <param name="formatString"></param>
+ public LayoutRendererAttribute(string formatString)
+ {
+ _formatString = formatString;
+ }
+
+ /// <summary>
+ /// The format string that can be used to invoke the layout renderer.
+ /// </summary>
+ public string FormatString
+ {
+ get { return _formatString; }
+ }
+
+ /// <summary>
+ /// Marks the specified layout renderer as ignoring padding (used mostly for
+ /// documentation generation).
+ /// </summary>
+ public bool IgnoresPadding
+ {
+ get { return _ignoresPadding; }
+ set { _ignoresPadding = value; }
+ }
+
+ /// <summary>
+ /// Marks the specified layout renderer as relying purely on the contents
+ /// of <see cref="LogEventInfo"/> only and not on any other information (such as thread-
+ /// </summary>
+ public bool UsingLogEventInfo
+ {
+ get { return _usingLogEventInfo; }
+ set { _usingLogEventInfo = value; }
+ }
+ }
+}
diff --git a/src/NLog/LayoutRendererCollection.cs b/src/NLog/LayoutRendererCollection.cs
new file mode 100644
index 0000000..00bd0cc
--- /dev/null
+++ b/src/NLog/LayoutRendererCollection.cs
@@ -0,0 +1,243 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace NLog
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A collection of elements of type LayoutRenderer
+ /// </summary>
+ public class LayoutRendererCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the LayoutRendererCollection class.
+ /// </summary>
+ public LayoutRendererCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the LayoutRendererCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new LayoutRendererCollection.
+ /// </param>
+ public LayoutRendererCollection(LayoutRenderer[]items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the LayoutRendererCollection class, containing elements
+ /// copied from another instance of LayoutRendererCollection
+ /// </summary>
+ /// <param name="items">
+ /// The LayoutRendererCollection whose elements are to be added to the new LayoutRendererCollection.
+ /// </param>
+ public LayoutRendererCollection(LayoutRendererCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this LayoutRendererCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this LayoutRendererCollection.
+ /// </param>
+ public virtual void AddRange(LayoutRenderer[]items)
+ {
+ foreach (LayoutRenderer item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another LayoutRendererCollection to the end of this LayoutRendererCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The LayoutRendererCollection whose elements are to be added to the end of this LayoutRendererCollection.
+ /// </param>
+ public virtual void AddRange(LayoutRendererCollection items)
+ {
+ foreach (LayoutRenderer item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type LayoutRenderer to the end of this LayoutRendererCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The LayoutRenderer to be added to the end of this LayoutRendererCollection.
+ /// </param>
+ public virtual void Add(LayoutRenderer value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic LayoutRenderer value is in this LayoutRendererCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The LayoutRenderer value to locate in this LayoutRendererCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this LayoutRendererCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(LayoutRenderer value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this LayoutRendererCollection
+ /// </summary>
+ /// <param name="value">
+ /// The LayoutRenderer value to locate in the LayoutRendererCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(LayoutRenderer value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the LayoutRendererCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the LayoutRenderer is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The LayoutRenderer to insert.
+ /// </param>
+ public virtual void Insert(int index, LayoutRenderer value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the LayoutRenderer at the given index in this LayoutRendererCollection.
+ /// </summary>
+ public virtual LayoutRenderer this[int index]
+ {
+ get { return (LayoutRenderer)this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific LayoutRenderer from this LayoutRendererCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The LayoutRenderer value to remove from this LayoutRendererCollection.
+ /// </param>
+ public virtual void Remove(LayoutRenderer value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by LayoutRendererCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(LayoutRendererCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public LayoutRenderer Current
+ {
+ get { return (LayoutRenderer)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (LayoutRenderer)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this LayoutRendererCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual LayoutRendererCollection.Enumerator GetEnumerator()
+ {
+ return new LayoutRendererCollection.Enumerator(this);
+ }
+ }
+}
diff --git a/src/NLog/LayoutRendererFactory.cs b/src/NLog/LayoutRendererFactory.cs
new file mode 100644
index 0000000..cb48d9f
--- /dev/null
+++ b/src/NLog/LayoutRendererFactory.cs
@@ -0,0 +1,206 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Reflection;
+using System.Globalization;
+
+using NLog.Internal;
+using NLog.LayoutRenderers;
+using NLog.Config;
+
+namespace NLog
+{
+ /// <summary>
+ /// A factory for layout renderers. Creates new layout renderers based on their names.
+ /// </summary>
+ public sealed class LayoutRendererFactory
+ {
+ private static TypeDictionary _targets = new TypeDictionary();
+
+ static LayoutRendererFactory()
+ {
+ foreach (Assembly a in ExtensionUtils.GetExtensionAssemblies())
+ {
+ AddLayoutRenderersFromAssembly(a, "");
+ }
+ }
+
+ private LayoutRendererFactory(){}
+
+ /// <summary>
+ /// Removes all layout renderer information from the factory.
+ /// </summary>
+ public static void Clear()
+ {
+ _targets.Clear();
+ }
+
+ /// <summary>
+ /// Scans the specified assembly for types marked with <see cref="LayoutRendererAttribute" /> and adds
+ /// them to the factory. Optionally it prepends the specified text to layout renderer names to avoid
+ /// naming collisions.
+ /// </summary>
+ /// <param name="theAssembly">The assembly to be scanned for layout renderers.</param>
+ /// <param name="prefix">The prefix to be prepended to layout renderer names.</param>
+ public static void AddLayoutRenderersFromAssembly(Assembly theAssembly, string prefix)
+ {
+ try
+ {
+ InternalLogger.Debug("AddLayoutRenderersFromAssembly('{0}')", theAssembly.FullName);
+ foreach (Type t in theAssembly.GetTypes())
+ {
+ LayoutRendererAttribute[]attributes = (LayoutRendererAttribute[])t.GetCustomAttributes(typeof(LayoutRendererAttribute), false);
+ if (attributes != null)
+ {
+ foreach (LayoutRendererAttribute attr in attributes)
+ {
+ if (PlatformDetector.IsSupportedOnCurrentRuntime(t))
+ {
+ AddLayoutRenderer(prefix + attr.FormatString, t);
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Failed to add layout renderers from '" + theAssembly.FullName + "': {0}", ex);
+ }
+ }
+
+ private static LayoutRenderer CreateUnknownLayoutRenderer(string name, string parameters)
+ {
+ return new LiteralLayoutRenderer("");
+ }
+
+ /// <summary>
+ /// Registers the specified layout renderer type to the factory under a specified name.
+ /// </summary>
+ /// <param name="name">The name of the layout renderer (e.g. <code>logger</code>, <code>message</code> or <code>aspnet-request</code>)</param>
+ /// <param name="t">The type of the new layout renderer</param>
+ /// <remarks>
+ /// The name specified in the name parameter can then be used
+ /// to create layout renderers.
+ /// </remarks>
+ public static void AddLayoutRenderer(string name, Type t)
+ {
+ InternalLogger.Trace("Registering layout renderer {0} for type '{1}')", name, t.FullName);
+ _targets[name.ToLower()] = t;
+ }
+
+ private static void ApplyLayoutRendererParameters(LayoutRenderer target, string parameterString)
+ {
+ int pos = 0;
+
+ while (pos < parameterString.Length)
+ {
+ int nameStartPos = pos;
+ while (pos < parameterString.Length && Char.IsWhiteSpace(parameterString[pos]))
+ {
+ pos++;
+ }
+ while (pos < parameterString.Length && parameterString[pos] != '=')
+ {
+ pos++;
+ }
+ int nameEndPos = pos;
+ if (nameStartPos == nameEndPos)
+ break;
+
+ pos++;
+
+ // we've got a name - now get a value
+ //
+
+ StringBuilder valueBuf = new StringBuilder();
+ while (pos < parameterString.Length)
+ {
+ if (parameterString[pos] == '\\')
+ {
+ valueBuf.Append(parameterString[pos + 1]);
+ pos += 2;
+ }
+ else if (parameterString[pos] == ':')
+ {
+ pos++;
+ break;
+ }
+ else
+ {
+ valueBuf.Append(parameterString[pos]);
+ pos++;
+ }
+ }
+
+ string name = parameterString.Substring(nameStartPos, nameEndPos - nameStartPos);
+ string value = valueBuf.ToString();
+
+ PropertyHelper.SetPropertyFromString(target, name, value, null);
+ }
+ }
+
+ /// <summary>
+ /// Creates the layout renderer object based on its layout renderer name and sets its properties from parameters string.
+ /// </summary>
+ /// <param name="name">The name of the layout renderer (e.g. <code>message</code> or <code>aspnet-request</code>)</param>
+ /// <param name="parameters">Parameters to the layout renderer.</param>
+ /// <returns>A new instance of the <see cref="LayoutRenderer"/> object.</returns>
+ public static LayoutRenderer CreateLayoutRenderer(string name, string parameters)
+ {
+ Type t = _targets[name.ToLower()];
+ if (t != null)
+ {
+ LayoutRenderer la = FactoryHelper.CreateInstance(t) as LayoutRenderer;
+ if (la != null)
+ {
+
+ if (parameters != null && parameters.Length > 0)
+ {
+ ApplyLayoutRendererParameters(la, parameters);
+ }
+
+ return la;
+ }
+ else
+ {
+ return CreateUnknownLayoutRenderer(name, parameters);
+ }
+ }
+ return CreateUnknownLayoutRenderer(name, parameters);
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/ASPNetApplication.cs b/src/NLog/LayoutRenderers/ASPNetApplication.cs
new file mode 100644
index 0000000..83657d5
--- /dev/null
+++ b/src/NLog/LayoutRenderers/ASPNetApplication.cs
@@ -0,0 +1,128 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.Web;
+
+using NLog.Config;
+using System.ComponentModel;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// ASP.NET Application variable.
+ /// </summary>
+ /// <remarks>
+ /// Use this layout renderer to insert the value of the specified variable stored
+ /// in the ASP.NET Application dictionary.
+ /// </remarks>
+ /// <example>
+ /// <para>You can set the value of an ASP.NET Application variable by using the following code:</para>
+ /// <code lang="C#">
+ /// <![CDATA[
+ /// HttpContext.Current.Application["myvariable"] = 123;
+ /// HttpContext.Current.Application["stringvariable"] = "aaa BBB";
+ /// HttpContext.Current.Application["anothervariable"] = DateTime.Now;
+ /// ]]>
+ /// </code>
+ /// <para>Example usage of ${aspnet-application}:</para>
+ /// <code lang="NLog Layout Renderer">
+ /// ${aspnet-application:variable=myvariable} - produces "123"
+ /// ${aspnet-application:variable=anothervariable} - produces "01/01/2006 00:00:00"
+ /// ${aspnet-application:variable=anothervariable:culture=pl-PL} - produces "2006-01-01 00:00:00"
+ /// ${aspnet-application:variable=myvariable:padding=5} - produces " 123"
+ /// ${aspnet-application:variable=myvariable:padding=-5} - produces "123 "
+ /// ${aspnet-application:variable=stringvariable:upperCase=true} - produces "AAA BBB"
+ /// </code>
+ /// </example>
+ [LayoutRenderer("aspnet-application")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class ASPNETApplicationValueLayoutRenderer: LayoutRenderer
+ {
+ private string _variable = null;
+
+ /// <summary>
+ /// The variable name.
+ /// </summary>
+ [RequiredParameter]
+ [DefaultParameter]
+ public string Variable
+ {
+ get { return _variable; }
+ set { _variable = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ if (_variable == null)
+ return 0;
+ else
+ return 64;
+ }
+
+ /// <summary>
+ /// Renders the specified ASP.NET Application variable and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ if (Variable == null)
+ return ;
+
+ HttpContext context = HttpContext.Current;
+ if (context == null)
+ return ;
+
+ if (context.Application == null)
+ return ;
+ builder.Append(ApplyPadding(Convert.ToString(context.Application[Variable], CultureInfo)));
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/ASPNetRequest.cs b/src/NLog/LayoutRenderers/ASPNetRequest.cs
new file mode 100644
index 0000000..255e693
--- /dev/null
+++ b/src/NLog/LayoutRenderers/ASPNetRequest.cs
@@ -0,0 +1,175 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.Web;
+
+using NLog.Config;
+using System.ComponentModel;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// ASP.NET Request variable
+ /// </summary>
+ /// <remarks>
+ /// Use this layout renderer to insert the value of the specified parameter of the
+ /// ASP.NET Request object.
+ /// </remarks>
+ /// <example>
+ /// <para>Example usage of ${aspnet-request}:</para>
+ /// <code lang="NLog Layout Renderer">
+ /// ${aspnet-request:item=v}
+ /// ${aspnet-request:querystring=v}
+ /// ${aspnet-request:form=v}
+ /// ${aspnet-request:cookie=v}
+ /// ${aspnet-request:serverVariable=v}
+ /// </code>
+ /// </example>
+ [LayoutRenderer("aspnet-request")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class ASPNETRequestValueLayoutRenderer : LayoutRenderer
+ {
+ private string _queryStringKey;
+ private string _formKey;
+ private string _cookie;
+ private string _item;
+ private string _serverVariable;
+
+ /// <summary>
+ /// The item name. The QueryString, Form, Cookies, or ServerVariables collection variables having the specified name are rendered.
+ /// </summary>
+ [DefaultParameter]
+ public string Item
+ {
+ get { return _item; }
+ set { _item = value; }
+ }
+
+
+ /// <summary>
+ /// The QueryString variable to be rendered.
+ /// </summary>
+ public string QueryString
+ {
+ get { return _queryStringKey; }
+ set { _queryStringKey = value; }
+ }
+
+ /// <summary>
+ /// The form variable to be rendered.
+ /// </summary>
+ public string Form
+ {
+ get { return _formKey; }
+ set { _formKey = value; }
+ }
+
+ /// <summary>
+ /// The cookie to be rendered.
+ /// </summary>
+ public string Cookie
+ {
+ get { return _cookie; }
+ set { _cookie = value; }
+ }
+
+ /// <summary>
+ /// The ServerVariables item to be rendered.
+ /// </summary>
+ public string ServerVariable
+ {
+ get { return _serverVariable; }
+ set { _serverVariable = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 64;
+ }
+
+ /// <summary>
+ /// Renders the specified ASP.NET Request variable and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ HttpContext context = HttpContext.Current;
+ if (context == null)
+ return ;
+
+ if (context.Request == null)
+ return ;
+ if (QueryString != null)
+ {
+ builder.Append(ApplyPadding(context.Request.QueryString[QueryString]));
+ }
+ else if (Form != null)
+ {
+ builder.Append(ApplyPadding(context.Request.Form[Form]));
+ }
+ else if (Cookie != null)
+ {
+ HttpCookie cookie = context.Request.Cookies[Cookie];
+
+ if (cookie != null)
+ builder.Append(ApplyPadding(cookie.Value));
+ }
+ else if (ServerVariable != null)
+ {
+ builder.Append(ApplyPadding(context.Request.ServerVariables[ServerVariable]));
+ }
+ else if (Item != null)
+ {
+ builder.Append(ApplyPadding(context.Request[Item]));
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/ASPNetSession.cs b/src/NLog/LayoutRenderers/ASPNetSession.cs
new file mode 100644
index 0000000..1e075a6
--- /dev/null
+++ b/src/NLog/LayoutRenderers/ASPNetSession.cs
@@ -0,0 +1,128 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.Web;
+
+using NLog.Config;
+using System.ComponentModel;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// ASP.NET Session variable.
+ /// </summary>
+ /// <remarks>
+ /// Use this layout renderer to insert the value of the specified variable stored
+ /// in the ASP.NET Session dictionary.
+ /// </remarks>
+ /// <example>
+ /// <para>You can set the value of an ASP.NET Session variable by using the following code:</para>
+ /// <code lang="C#">
+ /// <![CDATA[
+ /// HttpContext.Current.Session["myvariable"] = 123;
+ /// HttpContext.Current.Session["stringvariable"] = "aaa BBB";
+ /// HttpContext.Current.Session["anothervariable"] = DateTime.Now;
+ /// ]]>
+ /// </code>
+ /// <para>Example usage of ${aspnet-session}:</para>
+ /// <code lang="NLog Layout Renderer">
+ /// ${aspnet-session:variable=myvariable} - produces "123"
+ /// ${aspnet-session:variable=anothervariable} - produces "01/01/2006 00:00:00"
+ /// ${aspnet-session:variable=anothervariable:culture=pl-PL} - produces "2006-01-01 00:00:00"
+ /// ${aspnet-session:variable=myvariable:padding=5} - produces " 123"
+ /// ${aspnet-session:variable=myvariable:padding=-5} - produces "123 "
+ /// ${aspnet-session:variable=stringvariable:upperCase=true} - produces "AAA BBB"
+ /// </code>
+ /// </example>
+ [LayoutRenderer("aspnet-session")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class ASPNETSessionValueLayoutRenderer: LayoutRenderer
+ {
+ private string _variable = null;
+
+ /// <summary>
+ /// Session variable name.
+ /// </summary>
+ [DefaultParameter]
+ public string Variable
+ {
+ get { return _variable; }
+ set { _variable = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ if (Variable == null)
+ return 0;
+ else
+ return 64;
+ }
+
+ /// <summary>
+ /// Renders the specified ASP.NET Session value and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ if (Variable == null)
+ return ;
+
+ HttpContext context = HttpContext.Current;
+ if (context == null)
+ return ;
+
+ if (context.Session == null)
+ return ;
+
+ builder.Append(ApplyPadding(Convert.ToString(context.Session[Variable], CultureInfo)));
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/ASPNetSessionID.cs b/src/NLog/LayoutRenderers/ASPNetSessionID.cs
new file mode 100644
index 0000000..2fa18f9
--- /dev/null
+++ b/src/NLog/LayoutRenderers/ASPNetSessionID.cs
@@ -0,0 +1,86 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.Web;
+
+using NLog.Config;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// ASP.NET Session ID.
+ /// </summary>
+ [LayoutRenderer("aspnet-sessionid")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class ASPNETSessionIDLayoutRenderer: LayoutRenderer
+ {
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 64;
+ }
+
+ /// <summary>
+ /// Renders the ASP.NET Session ID appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ HttpContext context = HttpContext.Current;
+ if (context == null)
+ return ;
+
+ if (context.Session == null)
+ return ;
+
+ builder.Append(ApplyPadding(context.Session.SessionID));
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/ASPNetUserAuthType.cs b/src/NLog/LayoutRenderers/ASPNetUserAuthType.cs
new file mode 100644
index 0000000..0fa9880
--- /dev/null
+++ b/src/NLog/LayoutRenderers/ASPNetUserAuthType.cs
@@ -0,0 +1,92 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.Web;
+
+using NLog.Config;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// ASP.NET User variable
+ /// </summary>
+ [LayoutRenderer("aspnet-user-authtype")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class ASPNETUserAuthTypeLayoutRenderer : LayoutRenderer
+ {
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 64;
+ }
+
+ /// <summary>
+ /// Renders the specified ASP.NET User.Identity.AuthenticationType variable and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ HttpContext context = HttpContext.Current;
+ if (context == null)
+ return ;
+
+ if (context.User == null)
+ return ;
+
+ if (context.User.Identity == null)
+ return ;
+
+ if (!context.User.Identity.IsAuthenticated)
+ return;
+
+ builder.Append(ApplyPadding(context.User.Identity.AuthenticationType));
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/ASPNetUserIdentity.cs b/src/NLog/LayoutRenderers/ASPNetUserIdentity.cs
new file mode 100644
index 0000000..998f41d
--- /dev/null
+++ b/src/NLog/LayoutRenderers/ASPNetUserIdentity.cs
@@ -0,0 +1,89 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.Web;
+
+using NLog.Config;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// ASP.NET User variable
+ /// </summary>
+ [LayoutRenderer("aspnet-user-identity")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class ASPNETUserIdentityLayoutRenderer : LayoutRenderer
+ {
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 64;
+ }
+
+ /// <summary>
+ /// Renders the specified ASP.NET User.Identity.Name variable and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ HttpContext context = HttpContext.Current;
+ if (context == null)
+ return ;
+
+ if (context.User == null)
+ return ;
+
+ if (context.User.Identity == null)
+ return ;
+
+ builder.Append(ApplyPadding(context.User.Identity.Name));
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/BaseDir.cs b/src/NLog/LayoutRenderers/BaseDir.cs
new file mode 100644
index 0000000..4053049
--- /dev/null
+++ b/src/NLog/LayoutRenderers/BaseDir.cs
@@ -0,0 +1,128 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.IO;
+using NLog.Internal;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The current application domain's base directory.
+ /// </summary>
+ [LayoutRenderer("basedir")]
+ public class BaseDirLayoutRenderer: LayoutRenderer
+ {
+ private string _fileName = null;
+ private string _directoryName = null;
+ private string _baseDir;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="BaseDirLayoutRenderer"/>.
+ /// </summary>
+ public BaseDirLayoutRenderer()
+ {
+#if !NETCF
+ _baseDir = AppDomain.CurrentDomain.BaseDirectory;
+#else
+ _baseDir = CompactFrameworkHelper.GetExeBaseDir();
+#endif
+ }
+
+ /// <summary>
+ /// The name of the file to be Path.Combine()'d with with the base directory.
+ /// </summary>
+ public string File
+ {
+ get { return _fileName; }
+ set { _fileName = value; }
+ }
+
+ /// <summary>
+ /// The name of the directory to be Path.Combine()'d with with the base directory.
+ /// </summary>
+ public string Dir
+ {
+ get { return _directoryName; }
+ set { _directoryName = value; }
+ }
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the application base directory and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ if (File != null)
+ {
+ builder.Append(ApplyPadding(Path.Combine(_baseDir, File)));
+ }
+ else if (Dir != null)
+ {
+ builder.Append(ApplyPadding(Path.Combine(_baseDir, Dir)));
+ }
+ else
+ {
+ builder.Append(ApplyPadding(_baseDir));
+ }
+ }
+
+ /// <summary>
+ /// Determines whether the value produced by the layout renderer
+ /// is fixed per current app-domain.
+ /// </summary>
+ /// <returns><see langword="true"/></returns>
+ protected internal override bool IsAppDomainFixed()
+ {
+ return true;
+ }
+ }
+}
+
diff --git a/src/NLog/LayoutRenderers/CallSite.cs b/src/NLog/LayoutRenderers/CallSite.cs
new file mode 100644
index 0000000..9c6c78f
--- /dev/null
+++ b/src/NLog/LayoutRenderers/CallSite.cs
@@ -0,0 +1,175 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+using System;
+using System.Text;
+using System.Diagnostics;
+using System.Reflection;
+using System.IO;
+
+using NLog.Config;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The call site (class name, method name and source information)
+ /// </summary>
+ [LayoutRenderer("callsite",UsingLogEventInfo=true)]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class CallSiteLayoutRenderer: LayoutRenderer
+ {
+ private bool _className = true;
+ private bool _methodName = true;
+ private bool _sourceFile = false;
+ private bool _includeSourcePath = true;
+
+ /// <summary>
+ /// Render the class name.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool ClassName
+ {
+ get { return _className; }
+ set { _className = value; }
+ }
+
+ /// <summary>
+ /// Render the method name.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool MethodName
+ {
+ get { return _methodName; }
+ set { _methodName = value; }
+ }
+
+ /// <summary>
+ /// Render the source file name and line number.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool FileName
+ {
+ get { return _sourceFile; }
+ set { _sourceFile = value; }
+ }
+
+ /// <summary>
+ /// Include source file path.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool IncludeSourcePath
+ {
+ get { return _includeSourcePath; }
+ set { _includeSourcePath = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 200;
+ }
+
+ /// <summary>
+ /// Checks whether the stack trace is requested.
+ /// </summary>
+ /// <returns>2 when the source file information is requested, 1 otherwise.</returns>
+ protected internal override int NeedsStackTrace()
+ {
+ return _sourceFile ? 2 : 1;
+ }
+
+ /// <summary>
+ /// Renders the call site and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ StackFrame frame = logEvent.UserStackFrame;
+ if (frame != null)
+ {
+ StringBuilder sb2 = builder;
+ if (Padding != 0)
+ sb2 = new StringBuilder();
+
+ MethodBase method = frame.GetMethod();
+ if (ClassName)
+ {
+ sb2.Append(method.DeclaringType.FullName);
+ }
+ if (MethodName)
+ {
+ if (ClassName)
+ {
+ sb2.Append(".");
+ }
+ sb2.Append(method.Name);
+ }
+ if (FileName)
+ {
+ string fileName = frame.GetFileName();
+ if (fileName != null)
+ {
+ sb2.Append("(");
+ if (IncludeSourcePath)
+ {
+ sb2.Append(fileName);
+ }
+ else
+ {
+ sb2.Append(Path.GetFileName(fileName));
+ }
+ sb2.Append(":");
+ sb2.Append(frame.GetFileLineNumber());
+ sb2.Append(")");
+ }
+ }
+ if (Padding != 0)
+ builder.Append(ApplyPadding(sb2.ToString()));
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/Counter.cs b/src/NLog/LayoutRenderers/Counter.cs
new file mode 100644
index 0000000..5726a7e
--- /dev/null
+++ b/src/NLog/LayoutRenderers/Counter.cs
@@ -0,0 +1,144 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Globalization;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// A counter value (increases on each layout rendering).
+ /// </summary>
+ [LayoutRenderer("counter")]
+ public class CounterLayoutRenderer: LayoutRenderer
+ {
+ private int _value = 1;
+ private string _sequence = null;
+ private int _increment = 1;
+
+ /// <summary>
+ /// The initial value of the counter
+ /// </summary>
+ [System.ComponentModel.DefaultValue(1)]
+ public int Value
+ {
+ get { return _value; }
+ set { _value = value; }
+ }
+
+ /// <summary>
+ /// The value to be added to the counter after each layout rendering.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(1)]
+ public int Increment
+ {
+ get { return _increment; }
+ set { _increment = value; }
+ }
+
+ /// <summary>
+ /// The name of the sequence. Different named sequences can have individual values.
+ /// </summary>
+ public string Sequence
+ {
+ get { return _sequence; }
+ set { _sequence = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the specified counter value and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ int v;
+
+ if (Sequence != null)
+ {
+ v = GetNextSequenceValue(Sequence, Value, Increment);
+ }
+ else
+ {
+ v = _value;
+ _value += Increment;
+ }
+
+ builder.Append(ApplyPadding(v.ToString(Culture)));
+ }
+
+ private static Hashtable _sequences = new Hashtable();
+
+ private static int GetNextSequenceValue(string sequenceName, int defaultValue, int increment)
+ {
+ lock(_sequences)
+ {
+ object v = _sequences[sequenceName];
+ int val;
+
+ if (v == null)
+ {
+ val = defaultValue;
+ }
+ else
+ {
+ val = (int)v;
+ }
+
+ int retVal = val;
+
+ val += increment;
+ _sequences[sequenceName] = val;
+ return retVal;
+ }
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/Date.cs b/src/NLog/LayoutRenderers/Date.cs
new file mode 100644
index 0000000..119b67b
--- /dev/null
+++ b/src/NLog/LayoutRenderers/Date.cs
@@ -0,0 +1,86 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Globalization;
+using System.ComponentModel;
+using NLog.Config;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// A date and time in the specified format.
+ /// </summary>
+ [LayoutRenderer("date",UsingLogEventInfo=true)]
+ public class DateLayoutRenderer: LayoutRenderer
+ {
+ private string _format = "G";
+
+ /// <summary>
+ /// The date format. Can be any argument accepted by DateTime.ToString(format)
+ /// </summary>
+ [DefaultParameter]
+ public string Format
+ {
+ get { return _format; }
+ set { _format = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the current date and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ builder.Append(ApplyPadding(logEvent.TimeStamp.ToString(Format, CultureInfo)));
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/Environment.cs b/src/NLog/LayoutRenderers/Environment.cs
new file mode 100644
index 0000000..3d004f1
--- /dev/null
+++ b/src/NLog/LayoutRenderers/Environment.cs
@@ -0,0 +1,107 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.IO;
+
+using NLog.Config;
+using NLog.Internal;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The environment variable.
+ /// </summary>
+ [LayoutRenderer("environment")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class EnvironmentLayoutRenderer: LayoutRenderer
+ {
+ private string _variable = null;
+
+ /// <summary>
+ /// Name of the environment variable.
+ /// </summary>
+ [RequiredParameter]
+ [DefaultParameter]
+ public string Variable
+ {
+ get { return _variable; }
+ set { _variable = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the specified environment variable and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ if (Variable != null)
+ {
+ builder.Append(ApplyPadding(EnvironmentHelper.GetSafeEnvironmentVariable(Variable)));
+ }
+ }
+
+ /// <summary>
+ /// Determines whether the value produced by the layout renderer
+ /// is fixed per current app-domain.
+ /// </summary>
+ /// <returns><see langword="true"/></returns>
+ protected internal override bool IsAppDomainFixed()
+ {
+ // AFAIK there's no way to change the env variables
+ return true;
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/EventContext.cs b/src/NLog/LayoutRenderers/EventContext.cs
new file mode 100644
index 0000000..939be48
--- /dev/null
+++ b/src/NLog/LayoutRenderers/EventContext.cs
@@ -0,0 +1,92 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using NLog.Config;
+using System.ComponentModel;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// Log event context data
+ /// </summary>
+ [LayoutRenderer("event-context")]
+ public class EventContextLayoutRenderer : LayoutRenderer
+ {
+ private string _item;
+
+ /// <summary>
+ /// Name of the item.
+ /// </summary>
+ [RequiredParameter]
+ [DefaultParameter]
+ public string Item
+ {
+ get { return _item; }
+ set { _item = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the specified log event context item and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+#if NETCF_1_0
+ string msg = Convert.ToString(logEvent.Context[Item]);
+#else
+ string msg = Convert.ToString(logEvent.Context[Item], CultureInfo);
+#endif
+
+ builder.Append(ApplyPadding(msg));
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/Exception.cs b/src/NLog/LayoutRenderers/Exception.cs
new file mode 100644
index 0000000..4c374e2
--- /dev/null
+++ b/src/NLog/LayoutRenderers/Exception.cs
@@ -0,0 +1,199 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Text;
+using System.IO;
+
+using NLog.Internal;
+using NLog.Config;
+using System.ComponentModel;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// Exception information provided through
+ /// a call to one of the Logger.*Exception() methods.
+ /// </summary>
+ [LayoutRenderer("exception",UsingLogEventInfo=true)]
+ public class ExceptionLayoutRenderer: LayoutRenderer
+ {
+ private string _format;
+ private string _separator = " ";
+
+ delegate void ExceptionDataTarget(StringBuilder sb, Exception ex);
+
+ private ExceptionDataTarget[] _exceptionDataTargets = null;
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="ExceptionLayoutRenderer"/>.
+ /// </summary>
+ public ExceptionLayoutRenderer()
+ {
+ Format = "message";
+ }
+
+
+ /// <summary>
+ /// The format of the output. Must be a comma-separated list of exception
+ /// properties: Message, Type, ShortType, ToString, Method, StackTrace.
+ /// This parameter value is case-insensitive.
+ /// </summary>
+ [DefaultParameter]
+ public string Format
+ {
+ get { return _format; }
+ set { _format = value; CompileFormat(value); }
+ }
+
+ /// <summary>
+ /// The separator used to concatenate parts specified in the Format.
+ /// </summary>
+ public string Separator
+ {
+ get { return _separator; }
+ set { _separator = value; }
+ }
+
+ private void AppendMessage(StringBuilder sb, Exception ex) {
+ sb.Append(ex.Message);
+ }
+
+#if !NETCF
+ private void AppendMethod(StringBuilder sb, Exception ex) {
+ sb.Append(ex.TargetSite.ToString());
+ }
+
+ private void AppendStackTrace(StringBuilder sb, Exception ex)
+ {
+ sb.Append(ex.StackTrace);
+ }
+#endif
+
+ private void AppendToString(StringBuilder sb, Exception ex)
+ {
+ sb.Append(ex.ToString());
+ }
+
+ private void AppendType(StringBuilder sb, Exception ex)
+ {
+ sb.Append(ex.GetType().FullName);
+ }
+
+ private void AppendShortType(StringBuilder sb, Exception ex)
+ {
+ sb.Append(ex.GetType().Name);
+ }
+
+ private void CompileFormat(string format)
+ {
+ string[] parts = format.Replace(" ","").Split(',');
+ ArrayList dataTargets = new ArrayList();
+
+ foreach (string s in parts)
+ {
+ switch (s.ToLower())
+ {
+ case "message":
+ dataTargets.Add(new ExceptionDataTarget(AppendMessage));
+ break;
+
+ case "type":
+ dataTargets.Add(new ExceptionDataTarget(AppendType));
+ break;
+
+ case "shorttype":
+ dataTargets.Add(new ExceptionDataTarget(AppendShortType));
+ break;
+
+ case "tostring":
+ dataTargets.Add(new ExceptionDataTarget(AppendToString));
+ break;
+
+#if !NETCF
+ case "stacktrace":
+ dataTargets.Add(new ExceptionDataTarget(AppendStackTrace));
+ break;
+
+ case "method":
+ dataTargets.Add(new ExceptionDataTarget(AppendMethod));
+ break;
+#endif
+ default:
+ InternalLogger.Warn("Unknown exception data target: {0}", s);
+ break;
+
+ }
+ }
+ _exceptionDataTargets = (ExceptionDataTarget[])dataTargets.ToArray(typeof(ExceptionDataTarget));
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the specified exception information and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ if (logEvent.Exception != null)
+ {
+ StringBuilder sb2 = new StringBuilder(128);
+
+ for (int i = 0; i < _exceptionDataTargets.Length; ++i)
+ {
+ if (i != 0)
+ sb2.Append(Separator);
+ _exceptionDataTargets[i](sb2, logEvent.Exception);
+ }
+ builder.Append(ApplyPadding(sb2.ToString()));
+ }
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/FileContents.cs b/src/NLog/LayoutRenderers/FileContents.cs
new file mode 100644
index 0000000..4c92623
--- /dev/null
+++ b/src/NLog/LayoutRenderers/FileContents.cs
@@ -0,0 +1,127 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.IO;
+using NLog.Internal;
+using System.ComponentModel;
+using NLog.Config;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// Contents of the specified file.
+ /// </summary>
+ [LayoutRenderer("file-contents")]
+ public class FileContentsLayoutRenderer: LayoutRenderer
+ {
+ private Layout _fileName;
+ private System.Text.Encoding _encoding = System.Text.Encoding.Default;
+ private string _lastFileName = "";
+ private string _fileContents;
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 8;
+ }
+
+ /// <summary>
+ /// Name of the file.
+ /// </summary>
+ [DefaultParameter]
+ public Layout FileName
+ {
+ get { return _fileName; }
+ set { _fileName = value; }
+ }
+
+ /// <summary>
+ /// File encoding.
+ /// </summary>
+ /// <value>The encoding.</value>
+ public string Encoding
+ {
+ get { return _encoding.WebName; }
+ set { _encoding = System.Text.Encoding.GetEncoding(value); }
+ }
+
+ /// <summary>
+ /// Renders the contents of the specified file and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ lock (this)
+ {
+ string fileName = _fileName.GetFormattedMessage(logEvent);
+
+ if (fileName != _lastFileName)
+ {
+ ReadFileContents(fileName);
+ _lastFileName = fileName;
+ }
+ }
+ builder.Append(_fileContents);
+ }
+
+ private void ReadFileContents(string fileName)
+ {
+ _fileContents = "";
+
+ try
+ {
+ using (StreamReader sr = new StreamReader(fileName, _encoding))
+ {
+ _fileContents = sr.ReadToEnd();
+ }
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Warn("Cannot read file {0}: {1}", FileName, ex);
+ }
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/GC.cs b/src/NLog/LayoutRenderers/GC.cs
new file mode 100644
index 0000000..58cef4a
--- /dev/null
+++ b/src/NLog/LayoutRenderers/GC.cs
@@ -0,0 +1,162 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF && !MONO
+
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+
+using NLog.Internal;
+using NLog.Config;
+using System.Reflection;
+using System.Diagnostics;
+using System.ComponentModel;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The information about the garbage collector.
+ /// </summary>
+ [LayoutRenderer("gc")]
+ [SupportedRuntime(Framework=RuntimeFramework.DotNetFramework)]
+ public class GCLayoutRenderer: LayoutRenderer
+ {
+ /// <summary>
+ /// The property of System.GC to retrieve
+ /// </summary>
+ public enum GCProperty
+ {
+ /// <summary>
+ /// Total memory allocated
+ /// </summary>
+ TotalMemory,
+
+ /// <summary>
+ /// Total memory allocated (perform full garbage collection first)
+ /// </summary>
+ TotalMemoryForceCollection,
+
+ /// <summary>
+ /// Number of Gen0 collections.
+ /// </summary>
+ CollectionCount0,
+
+ /// <summary>
+ /// Number of Gen1 collections.
+ /// </summary>
+ CollectionCount1,
+
+ /// <summary>
+ /// Number of Gen2 collections.
+ /// </summary>
+ CollectionCount2,
+
+ /// <summary>
+ /// Maximum generation number supported by GC.
+ /// </summary>
+ MaxGeneration,
+ }
+
+ private GCProperty _property = GCProperty.TotalMemory;
+
+ /// <summary>
+ /// The property to retrieve.
+ /// </summary>
+ [DefaultValue("TotalMemory")]
+ public GCProperty Property
+ {
+ get { return _property; }
+ set { _property = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the selected process information.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ object value = null;
+
+ switch (_property)
+ {
+ case GCProperty.TotalMemory:
+ value = GC.GetTotalMemory(false);
+ break;
+
+ case GCProperty.TotalMemoryForceCollection:
+ value = GC.GetTotalMemory(true);
+ break;
+
+#if DOTNET2
+ case GCProperty.CollectionCount0:
+ value = GC.CollectionCount(0);
+ break;
+
+ case GCProperty.CollectionCount1:
+ value = GC.CollectionCount(1);
+ break;
+
+ case GCProperty.CollectionCount2:
+ value = GC.CollectionCount(2);
+ break;
+#endif
+
+ case GCProperty.MaxGeneration:
+ value = GC.MaxGeneration;
+ break;
+ }
+
+ builder.Append(ApplyPadding(Convert.ToString(value, CultureInfo)));
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/GCD.cs b/src/NLog/LayoutRenderers/GCD.cs
new file mode 100644
index 0000000..27653a2
--- /dev/null
+++ b/src/NLog/LayoutRenderers/GCD.cs
@@ -0,0 +1,87 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using NLog.Config;
+using System.ComponentModel;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// Global Diagnostics Context item. Provided for compatibility with log4net.
+ /// </summary>
+ [LayoutRenderer("gdc")]
+ public class GDCLayoutRenderer : LayoutRenderer
+ {
+ private string _item;
+
+ /// <summary>
+ /// Name of the item.
+ /// </summary>
+ [RequiredParameter]
+ [DefaultParameter]
+ public string Item
+ {
+ get { return _item; }
+ set { _item = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return GDC.Get(Item).Length;
+ }
+
+ /// <summary>
+ /// Renders the specified Global Diagnostics Context item and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ string msg = GDC.Get(Item);
+ builder.Append(ApplyPadding(msg));
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/Guid.cs b/src/NLog/LayoutRenderers/Guid.cs
new file mode 100644
index 0000000..2d2e53b
--- /dev/null
+++ b/src/NLog/LayoutRenderers/Guid.cs
@@ -0,0 +1,90 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+using System;
+using System.Text;
+using System.Globalization;
+
+using NLog.Config;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// Globally-unique identifier (GUID).
+ /// </summary>
+ [LayoutRenderer("guid")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class GuidLayoutRenderer: LayoutRenderer
+ {
+ private string _format = "N";
+
+ /// <summary>
+ /// The GUID format as accepted by Guid.ToString() method.
+ /// </summary>
+ [System.ComponentModel.DefaultValue("N")]
+ public string Format
+ {
+ get { return _format; }
+ set { _format = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders a newly generated GUID string and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ builder.Append(ApplyPadding(Guid.NewGuid().ToString(Format)));
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/Identity.cs b/src/NLog/LayoutRenderers/Identity.cs
new file mode 100644
index 0000000..6c038bf
--- /dev/null
+++ b/src/NLog/LayoutRenderers/Identity.cs
@@ -0,0 +1,194 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !(NETCF)
+using System;
+using System.Text;
+using System.Security.Principal;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// Thread identity information (name and authentication information)
+ /// </summary>
+ [LayoutRenderer("identity")]
+ public class IdentityLayoutRenderer: LayoutRenderer
+ {
+ private bool _name = true;
+ private bool _authType = true;
+ private bool _isAuthenticated = true;
+ private bool _fsNormalize = false;
+ private string _separator = ":";
+
+ /// <summary>
+ /// The separator to be used when concatenating
+ /// parts of identity information.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(":")]
+ public string Separator
+ {
+ get { return _separator; }
+ set { _separator = value; }
+ }
+
+ /// <summary>
+ /// Render Thread.CurrentPrincipal.Identity.Name.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool Name
+ {
+ get { return _name; }
+ set { _name = value; }
+ }
+
+ /// <summary>
+ /// Render Thread.CurrentPrincipal.Identity.AuthenticationType.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool AuthType
+ {
+ get { return _authType; }
+ set { _authType = value; }
+ }
+
+ /// <summary>
+ /// Render Thread.CurrentPrincipal.Identity.IsAuthenticated.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool IsAuthenticated
+ {
+ get { return _isAuthenticated; }
+ set { _isAuthenticated = value; }
+ }
+
+ /// <summary>
+ /// When true the output of this renderer is modified so it can be used as a part of file path
+ /// (illegal characters are replaced with '_')
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool FSNormalize
+ {
+ get { return _fsNormalize; }
+ set { _fsNormalize = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the specified identity information and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ IPrincipal principal = System.Threading.Thread.CurrentPrincipal;
+ if (principal != null)
+ {
+ IIdentity identity = principal.Identity;
+ if (identity != null)
+ {
+ StringBuilder sb2 = builder;
+ if (Padding != 0)
+ sb2 = new StringBuilder();
+ int sbstart = sb2.Length;
+ bool first = true;
+
+ if (_isAuthenticated)
+ {
+ if (!first)
+ {
+ sb2.Append(_separator);
+ }
+ if (identity.IsAuthenticated)
+ {
+ sb2.Append("auth");
+ }
+ else
+ {
+ sb2.Append("notauth");
+ }
+ first = false;
+ }
+
+ if (_authType)
+ {
+ if (!first)
+ {
+ sb2.Append(_separator);
+ }
+ sb2.Append(identity.AuthenticationType);
+ first = false;
+ }
+
+ if (_name)
+ {
+ if (!first)
+ {
+ sb2.Append(_separator);
+ }
+ sb2.Append(identity.Name);
+ first = false;
+ }
+
+ if (_fsNormalize)
+ {
+ for (int i=sbstart; i<sb2.Length; i++)
+ {
+ char c = sb2[i];
+ if (!Char.IsLetterOrDigit(c) && c != '_' && c != '-' && c != '.') sb2[i] = '_';
+ }
+ }
+
+ if (Padding != 0)
+ builder.Append(ApplyPadding(sb2.ToString()));
+ }
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/Level.cs b/src/NLog/LayoutRenderers/Level.cs
new file mode 100644
index 0000000..22532e3
--- /dev/null
+++ b/src/NLog/LayoutRenderers/Level.cs
@@ -0,0 +1,71 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The log level.
+ /// </summary>
+ [LayoutRenderer("level",UsingLogEventInfo=true)]
+ public class LevelLayoutRenderer: LayoutRenderer
+ {
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 8;
+ }
+
+ /// <summary>
+ /// Renders the current log level and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ builder.Append(ApplyPadding(logEvent.Level.ToString()));
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/Literal.cs b/src/NLog/LayoutRenderers/Literal.cs
new file mode 100644
index 0000000..66c75c7
--- /dev/null
+++ b/src/NLog/LayoutRenderers/Literal.cs
@@ -0,0 +1,104 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// A string literal.
+ /// </summary>
+ /// <remarks>
+ /// This is used to escape '${' sequence
+ /// as ;${literal:text=${}'
+ /// </remarks>
+ [LayoutRenderer("literal", UsingLogEventInfo=true, IgnoresPadding=true)]
+ public class LiteralLayoutRenderer: LayoutRenderer
+ {
+ private string _txt;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="LiteralLayoutRenderer"/>.
+ /// </summary>
+ public LiteralLayoutRenderer()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="LiteralLayoutRenderer"/> and sets the
+ /// literal text value.
+ /// </summary>
+ /// <param name="txt">The literal text value.</param>
+ /// <remarks>This is used by the layout compiler.</remarks>
+ public LiteralLayoutRenderer(string txt)
+ {
+ _txt = txt;
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return _txt.Length;
+ }
+
+ /// <summary>
+ /// Renders the specified string literal and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ builder.Append(_txt);
+ }
+
+ /// <summary>
+ /// Literal text.
+ /// </summary>
+ public string Text
+ {
+ get { return _txt; }
+ set { _txt = value; }
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/Log4JXmlEvent.cs b/src/NLog/LayoutRenderers/Log4JXmlEvent.cs
new file mode 100644
index 0000000..96c4625
--- /dev/null
+++ b/src/NLog/LayoutRenderers/Log4JXmlEvent.cs
@@ -0,0 +1,255 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.IO;
+using System.Xml;
+using System.Diagnostics;
+using System.Reflection;
+
+using NLog.Config;
+using NLog.Targets;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// XML event description compatible with log4j, Chainsaw and NLogViewer
+ /// </summary>
+ [LayoutRenderer("log4jxmlevent",UsingLogEventInfo=true)]
+ public class Log4JXmlEventLayoutRenderer: LayoutRenderer
+ {
+ private string _appInfo;
+ private bool _includeMDC = false;
+ private bool _includeNDC = false;
+ private bool _includeNLogData = true;
+ private bool _indentXml = false;
+ private static DateTime _log4jDateBase = new DateTime(1970, 1, 1);
+ private NLogViewerParameterInfoCollection _parameters = new NLogViewerParameterInfoCollection();
+
+ /// <summary>
+ /// Creates a new instance of <see cref="Log4JXmlEventLayoutRenderer"/> and initializes default values.
+ /// </summary>
+ public Log4JXmlEventLayoutRenderer()
+ {
+#if NETCF
+ AppInfo = ".NET CF Application";
+#else
+ AppInfo = String.Format("{0}({1})", AppDomain.CurrentDomain.FriendlyName, NLog.Internal.ThreadIDHelper.Instance.CurrentProcessID);
+#endif
+ }
+
+ /// <summary>
+ /// Include NLog-specific extensions to log4j schema.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool IncludeNLogData
+ {
+ get { return _includeNLogData; }
+ set { _includeNLogData = value; }
+ }
+
+ /// <summary>
+ /// Whether the XML should use spaces for indentation.
+ /// </summary>
+ public bool IndentXml
+ {
+ get { return _indentXml; }
+ set { _indentXml = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 512;
+ }
+
+ /// <summary>
+ /// The AppInfo field. By default it's the friendly name of the current AppDomain.
+ /// </summary>
+ public string AppInfo
+ {
+ get { return _appInfo; }
+ set { _appInfo = value; }
+ }
+
+#if !NETCF
+ private bool _includeCallSite = false;
+ private bool _includeSourceInfo = false;
+
+ /// <summary>
+ /// Include call site (class and method name) in the information sent over the network.
+ /// </summary>
+ public bool IncludeCallSite
+ {
+ get { return _includeCallSite; }
+ set { _includeCallSite = value; }
+ }
+
+ /// <summary>
+ /// Include source info (file name and line number) in the information sent over the network.
+ /// </summary>
+ public bool IncludeSourceInfo
+ {
+ get { return _includeSourceInfo; }
+ set { _includeSourceInfo = value; }
+ }
+#endif
+
+ /// <summary>
+ /// Include MDC dictionary in the information sent over the network.
+ /// </summary>
+ public bool IncludeMDC
+ {
+ get { return _includeMDC; }
+ set { _includeMDC = value; }
+ }
+
+ /// <summary>
+ /// Include NDC stack.
+ /// </summary>
+ public bool IncludeNDC
+ {
+ get { return _includeNDC; }
+ set { _includeNDC = value; }
+ }
+
+ internal NLogViewerParameterInfoCollection Parameters
+ {
+ get { return _parameters; }
+ set { _parameters = value; }
+ }
+
+ /// <summary>
+ /// Renders the XML logging event and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ StringWriter sw = new StringWriter(builder);
+ XmlTextWriter xtw = new XmlTextWriter(sw);
+ if (IndentXml)
+ xtw.Formatting = Formatting.Indented;
+
+ xtw.WriteStartElement("log4j:event");
+ xtw.WriteAttributeString("logger", logEvent.LoggerName);
+ xtw.WriteAttributeString("level", logEvent.Level.Name.ToUpper());
+ xtw.WriteAttributeString("timestamp", Convert.ToString((long)(logEvent.TimeStamp.ToUniversalTime() - _log4jDateBase).TotalMilliseconds));
+#if !NETCF
+ xtw.WriteAttributeString("thread", NLog.Internal.ThreadIDHelper.Instance.CurrentThreadID.ToString());
+#else
+ xtw.WriteElementString("thread", "");
+#endif
+
+ xtw.WriteElementString("log4j:message", logEvent.FormattedMessage);
+ if (IncludeNDC)
+ {
+ xtw.WriteElementString("log4j:NDC", NDC.GetAllMessages(" "));
+ }
+#if !NETCF
+ if (IncludeCallSite || IncludeSourceInfo)
+ {
+ System.Diagnostics.StackFrame frame = logEvent.UserStackFrame;
+ MethodBase methodBase = frame.GetMethod();
+ Type type = methodBase.DeclaringType;
+
+ xtw.WriteStartElement("log4j:locationinfo");
+ xtw.WriteAttributeString("class", type.FullName);
+ xtw.WriteAttributeString("method", methodBase.ToString());
+ if (IncludeSourceInfo)
+ {
+ xtw.WriteAttributeString("file", frame.GetFileName());
+ xtw.WriteAttributeString("line", frame.GetFileLineNumber().ToString());
+ }
+ xtw.WriteEndElement();
+
+ if (IncludeNLogData)
+ {
+ xtw.WriteElementString("nlog:eventSequenceNumber", logEvent.SequenceID.ToString());
+ xtw.WriteStartElement("nlog:locationinfo");
+ xtw.WriteAttributeString("assembly", type.Assembly.FullName);
+ xtw.WriteEndElement();
+ }
+ }
+#endif
+ xtw.WriteStartElement("log4j:properties");
+ if (IncludeMDC)
+ {
+ foreach (System.Collections.DictionaryEntry entry in MDC.GetThreadDictionary())
+ {
+ xtw.WriteStartElement("log4j:data");
+ xtw.WriteAttributeString("name", Convert.ToString(entry.Key));
+ xtw.WriteAttributeString("value", Convert.ToString(entry.Value));
+ xtw.WriteEndElement();
+ }
+ }
+
+ foreach (NLogViewerParameterInfo parameter in Parameters)
+ {
+ xtw.WriteStartElement("log4j:data");
+ xtw.WriteAttributeString("name", parameter.Name);
+ xtw.WriteAttributeString("value", parameter.CompiledLayout.GetFormattedMessage(logEvent));
+ xtw.WriteEndElement();
+ }
+
+ xtw.WriteStartElement("log4j:data");
+ xtw.WriteAttributeString("name", "log4japp");
+ xtw.WriteAttributeString("value", AppInfo);
+ xtw.WriteEndElement();
+
+ xtw.WriteStartElement("log4j:data");
+ xtw.WriteAttributeString("name", "log4jmachinename");
+#if NETCF
+ xtw.WriteAttributeString("value", "netcf");
+#else
+ xtw.WriteAttributeString("value", NLog.LayoutRenderers.MachineNameLayoutRenderer.MachineName);
+#endif
+ xtw.WriteEndElement();
+ xtw.WriteEndElement();
+
+ xtw.WriteEndElement();
+ xtw.Flush();
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/LoggerName.cs b/src/NLog/LayoutRenderers/LoggerName.cs
new file mode 100644
index 0000000..5496c29
--- /dev/null
+++ b/src/NLog/LayoutRenderers/LoggerName.cs
@@ -0,0 +1,87 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Globalization;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The logger name.
+ /// </summary>
+ [LayoutRenderer("logger",UsingLogEventInfo=true)]
+ public class LoggerNameLayoutRenderer: LayoutRenderer
+ {
+ private bool _shortName = false;
+
+ /// <summary>
+ /// Render short logger name (the part after the trailing dot character).
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool ShortName
+ {
+ get { return _shortName; }
+ set { _shortName = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the logger name and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ if (ShortName)
+ builder.Append(ApplyPadding(logEvent.LoggerShortName));
+ else
+ builder.Append(ApplyPadding(logEvent.LoggerName));
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/LongDate.cs b/src/NLog/LayoutRenderers/LongDate.cs
new file mode 100644
index 0000000..13ebcef
--- /dev/null
+++ b/src/NLog/LayoutRenderers/LongDate.cs
@@ -0,0 +1,107 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Globalization;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The date and time in a long, sortable format yyyy-MM-dd HH:mm:ss.mmm
+ /// </summary>
+ [LayoutRenderer("longdate",UsingLogEventInfo=true)]
+ public class LongDateLayoutRenderer: LayoutRenderer
+ {
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 24;
+ }
+
+ private void Append2DigitsZeroPadded(StringBuilder builder, int number)
+ {
+ builder.Append((char)((number / 10) + '0'));
+ builder.Append((char)((number % 10) + '0'));
+ }
+
+ private void Append4DigitsZeroPadded(StringBuilder builder, int number)
+ {
+ builder.Append((char)((number / 1000 % 10) + '0'));
+ builder.Append((char)((number / 100 % 10) + '0'));
+ builder.Append((char)((number / 10 % 10) + '0'));
+ builder.Append((char)((number / 1 % 10) + '0'));
+ }
+
+ /// <summary>
+ /// Renders the date in the long format (yyyy-MM-dd HH:mm:ss.mmm) and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ if (NeedPadding())
+ {
+ builder.Append(ApplyPadding(logEvent.TimeStamp.ToString("yyyy-MM-dd HH:mm:ss.ffff", CultureInfo)));
+ }
+ else
+ {
+ DateTime dt = logEvent.TimeStamp;
+
+ builder.Append(dt.Year);
+ builder.Append('-');
+ Append2DigitsZeroPadded(builder, dt.Month);
+ builder.Append('-');
+ Append2DigitsZeroPadded(builder, dt.Day);
+ builder.Append(' ');
+ Append2DigitsZeroPadded(builder, dt.Hour);
+ builder.Append(':');
+ Append2DigitsZeroPadded(builder, dt.Minute);
+ builder.Append(':');
+ Append2DigitsZeroPadded(builder, dt.Second);
+ builder.Append('.');
+ Append4DigitsZeroPadded(builder, (int)(dt.Ticks % 10000000) / 1000);
+ }
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/MDC.cs b/src/NLog/LayoutRenderers/MDC.cs
new file mode 100644
index 0000000..ae6f8b4
--- /dev/null
+++ b/src/NLog/LayoutRenderers/MDC.cs
@@ -0,0 +1,87 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using NLog.Config;
+using System.ComponentModel;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// Mapped Diagnostic Context item. Provided for compatibility with log4net.
+ /// </summary>
+ [LayoutRenderer("mdc")]
+ public class MDCLayoutRenderer: LayoutRenderer
+ {
+ private string _item;
+
+ /// <summary>
+ /// Name of the item.
+ /// </summary>
+ [RequiredParameter]
+ [DefaultParameter]
+ public string Item
+ {
+ get { return _item; }
+ set { _item = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return MDC.Get(Item).Length;
+ }
+
+ /// <summary>
+ /// Renders the specified MDC item and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ string msg = MDC.Get(Item);
+ builder.Append(ApplyPadding(msg));
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/MachineName.cs b/src/NLog/LayoutRenderers/MachineName.cs
new file mode 100644
index 0000000..a7b0285
--- /dev/null
+++ b/src/NLog/LayoutRenderers/MachineName.cs
@@ -0,0 +1,110 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.IO;
+using NLog.Internal;
+
+using NLog.Config;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The machine name that the process is running on.
+ /// </summary>
+ [LayoutRenderer("machinename")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class MachineNameLayoutRenderer: LayoutRenderer
+ {
+ static string _machineName = GetMachineName();
+
+ internal static string MachineName
+ {
+ get { return _machineName; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return _machineName.Length;
+ }
+
+ /// <summary>
+ /// Renders the machine name and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ builder.Append(ApplyPadding(_machineName));
+ }
+
+ private static string GetMachineName()
+ {
+ try
+ {
+ return Environment.MachineName;
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Warn("Error getting machine name: {0}", ex);
+ return String.Empty;
+ }
+ }
+
+ /// <summary>
+ /// Determines whether the value produced by the layout renderer
+ /// is fixed per current app-domain.
+ /// </summary>
+ /// <returns><see langword="true"/></returns>
+ protected internal override bool IsAppDomainFixed()
+ {
+ return true;
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/Message.cs b/src/NLog/LayoutRenderers/Message.cs
new file mode 100644
index 0000000..7c0deab
--- /dev/null
+++ b/src/NLog/LayoutRenderers/Message.cs
@@ -0,0 +1,100 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The formatted log message.
+ /// </summary>
+ [LayoutRenderer("message",UsingLogEventInfo=true)]
+ public class MessageLayoutRenderer: LayoutRenderer
+ {
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return logEvent.Message.Length;
+ }
+
+ /// <summary>
+ /// Renders the log message including any positional parameters and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ if (NeedPadding())
+ {
+ builder.Append(ApplyPadding(logEvent.FormattedMessage));
+ }
+ else
+ {
+ if (logEvent.Parameters == null || logEvent.Parameters.Length == 0)
+ {
+ builder.Append(logEvent.Message);
+ }
+ else
+ {
+ if (logEvent.FormatProvider != null)
+ {
+#if NETCF
+ builder.Append(String.Format(logEvent.FormatProvider, logEvent.Message, logEvent.Parameters));
+#else
+ builder.AppendFormat(logEvent.FormatProvider, logEvent.Message, logEvent.Parameters);
+#endif
+ }
+ else
+ {
+#if NETCF
+ builder.Append(String.Format(logEvent.Message, logEvent.Parameters));
+#else
+ builder.AppendFormat(logEvent.Message, logEvent.Parameters);
+#endif
+ }
+ };
+ }
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/NDC.cs b/src/NLog/LayoutRenderers/NDC.cs
new file mode 100644
index 0000000..925c420
--- /dev/null
+++ b/src/NLog/LayoutRenderers/NDC.cs
@@ -0,0 +1,118 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+
+using NLog.LayoutRenderers;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// Nested Diagnostic Context item. Provided for compatibility with log4net.
+ /// </summary>
+ [LayoutRenderer("ndc")]
+ public class NDCLayoutRenderer: LayoutRenderer
+ {
+ private int _topFrames = -1;
+ private int _bottomFrames = -1;
+ private string _separator = " ";
+
+ /// <summary>
+ /// The number of top stack frames to be rendered.
+ /// </summary>
+ public int TopFrames
+ {
+ get { return _topFrames; }
+ set { _topFrames = value; }
+ }
+
+ /// <summary>
+ /// The number of bottom stack frames to be rendered.
+ /// </summary>
+ public int BottomFrames
+ {
+ get { return _bottomFrames; }
+ set { _bottomFrames = value; }
+ }
+
+ /// <summary>
+ /// The separator to be used for concatenating NDC output.
+ /// </summary>
+ public string Separator
+ {
+ get { return _separator; }
+ set { _separator = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 0;
+ }
+
+ /// <summary>
+ /// Renders the specified NDC item and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ string msg;
+
+ if (TopFrames != - 1)
+ {
+ msg = NDC.GetTopMessages(TopFrames, Separator);
+ }
+ else if (BottomFrames != - 1)
+ {
+ msg = NDC.GetBottomMessages(BottomFrames, Separator);
+ }
+ else
+ {
+ msg = NDC.GetAllMessages(Separator);
+ }
+ builder.Append(ApplyPadding(msg));
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/NLogDir.cs b/src/NLog/LayoutRenderers/NLogDir.cs
new file mode 100644
index 0000000..fe2fc77
--- /dev/null
+++ b/src/NLog/LayoutRenderers/NLogDir.cs
@@ -0,0 +1,132 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.IO;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The directory where NLog.dll is located.
+ /// </summary>
+ [LayoutRenderer("nlogdir")]
+ public class NLogDirLayoutRenderer: LayoutRenderer
+ {
+ private string _fileName = null;
+ private string _directoryName = null;
+ private static string _nlogDir;
+
+ static NLogDirLayoutRenderer()
+ {
+#if !NETCF
+ _nlogDir = Path.GetDirectoryName(typeof(LogManager).Assembly.Location);
+#else
+ _nlogDir = Path.GetDirectoryName(typeof(LogManager).Assembly.GetName().CodeBase);
+#endif
+ }
+
+ /// <summary>
+ /// The name of the file to be Path.Combine()'d with the directory name.
+ /// </summary>
+ public string File
+ {
+ get { return _fileName; }
+ set { _fileName = value; }
+ }
+
+ /// <summary>
+ /// The name of the directory to be Path.Combine()'d with the directory name.
+ /// </summary>
+ public string Dir
+ {
+ get { return _directoryName; }
+ set { _directoryName = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ private string NLogDir
+ {
+ get { return _nlogDir; }
+ }
+
+ /// <summary>
+ /// Renders the directory where NLog is located and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ string baseDir = NLogDir;
+
+ if (File != null)
+ {
+ builder.Append(ApplyPadding(Path.Combine(baseDir, File)));
+ }
+ else if (Dir != null)
+ {
+ builder.Append(ApplyPadding(Path.Combine(baseDir, Dir)));
+ }
+ else
+ {
+ builder.Append(ApplyPadding(baseDir));
+ }
+ }
+
+ /// <summary>
+ /// Determines whether the value produced by the layout renderer
+ /// is fixed per current app-domain.
+ /// </summary>
+ /// <returns><see langword="true"/></returns>
+ protected internal override bool IsAppDomainFixed()
+ {
+ return true;
+ }
+ }
+}
+
diff --git a/src/NLog/LayoutRenderers/NewLine.cs b/src/NLog/LayoutRenderers/NewLine.cs
new file mode 100644
index 0000000..f7dddbb
--- /dev/null
+++ b/src/NLog/LayoutRenderers/NewLine.cs
@@ -0,0 +1,75 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// A newline literal.
+ /// </summary>
+ [LayoutRenderer("newline",IgnoresPadding=true)]
+ public class NewLine: LayoutRenderer
+ {
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 2;
+ }
+
+ /// <summary>
+ /// Renders the specified string literal and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+#if NETCF
+ builder.Append("\n");
+#else
+ builder.Append(Environment.NewLine);
+#endif
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/PerformanceCounter.cs b/src/NLog/LayoutRenderers/PerformanceCounter.cs
new file mode 100644
index 0000000..59d3a5c
--- /dev/null
+++ b/src/NLog/LayoutRenderers/PerformanceCounter.cs
@@ -0,0 +1,181 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.IO;
+using System.Diagnostics;
+
+using NLog.Config;
+using NLog.Internal;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The performance counter.
+ /// </summary>
+ [LayoutRenderer("performancecounter")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class PerformanceCounterLayoutRenderer: LayoutRenderer
+ {
+ private string _categoryName = null;
+ private string _counterName = null;
+ private string _instanceName = null;
+ private string _machineName = null;
+ private PerformanceCounter _perfCounter = null;
+
+ /// <summary>
+ /// Name of the counter category.
+ /// </summary>
+ [RequiredParameter]
+ public string Category
+ {
+ get { return _categoryName; }
+ set
+ {
+ _categoryName = value;
+ InvalidatePerformanceCounter();
+ }
+ }
+
+ /// <summary>
+ /// Name of the performance counter.
+ /// </summary>
+ [RequiredParameter]
+ public string Counter
+ {
+ get { return _counterName; }
+ set
+ {
+ _counterName = value;
+ InvalidatePerformanceCounter();
+ }
+ }
+
+ /// <summary>
+ /// Name of the performance counter instance (e.g. _Global_).
+ /// </summary>
+ public string Instance
+ {
+ get { return _instanceName; }
+ set
+ {
+ _instanceName = value;
+ InvalidatePerformanceCounter();
+ }
+ }
+
+ /// <summary>
+ /// Name of the machine to read the performance counter from.
+ /// </summary>
+ public string MachineName
+ {
+ get { return _machineName; }
+ set
+ {
+ _machineName = value;
+ InvalidatePerformanceCounter();
+ }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ private void CreatePerformanceCounter()
+ {
+ if (_perfCounter == null)
+ {
+ lock (this)
+ {
+ if (_perfCounter == null)
+ {
+ if (_machineName != null)
+ {
+ _perfCounter = new PerformanceCounter(_categoryName, _counterName, _instanceName, _machineName);
+ }
+ else
+ {
+ _perfCounter = new PerformanceCounter(_categoryName, _counterName, _instanceName, true);
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Closes currently open performance counter (if any).
+ /// </summary>
+ private void InvalidatePerformanceCounter()
+ {
+ if (_perfCounter != null)
+ {
+ lock (this)
+ {
+ if (_perfCounter != null)
+ {
+ _perfCounter.Close();
+ _perfCounter = null;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Renders the specified environment variable and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ CreatePerformanceCounter();
+ builder.Append(ApplyPadding(_perfCounter.NextValue().ToString(CultureInfo)));
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/ProcessID.cs b/src/NLog/LayoutRenderers/ProcessID.cs
new file mode 100644
index 0000000..1139b99
--- /dev/null
+++ b/src/NLog/LayoutRenderers/ProcessID.cs
@@ -0,0 +1,84 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+
+using NLog.Internal;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The identifier of the current process.
+ /// </summary>
+ [LayoutRenderer("processid")]
+ public class ProcessIDLayoutRenderer: LayoutRenderer
+ {
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the current process ID.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ builder.Append(ApplyPadding(ThreadIDHelper.Instance.CurrentProcessID.ToString()));
+ }
+
+ /// <summary>
+ /// Determines whether the value produced by the layout renderer
+ /// is fixed per current app-domain.
+ /// </summary>
+ /// <returns><see langword="true"/></returns>
+ protected internal override bool IsAppDomainFixed()
+ {
+ return true;
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/ProcessInfo.cs b/src/NLog/LayoutRenderers/ProcessInfo.cs
new file mode 100644
index 0000000..0b4cb68
--- /dev/null
+++ b/src/NLog/LayoutRenderers/ProcessInfo.cs
@@ -0,0 +1,211 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF && !MONO
+
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+
+using NLog.Internal;
+using NLog.Config;
+using System.Reflection;
+using System.Diagnostics;
+using System.ComponentModel;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The information about the running process.
+ /// </summary>
+ [LayoutRenderer("processinfo")]
+ [SupportedRuntime(Framework=RuntimeFramework.DotNetFramework)]
+ public class ProcessInfoLayoutRenderer: LayoutRenderer
+ {
+ /// <summary>
+ /// The property of System.Diagnostics.Process to retrieve
+ /// </summary>
+ public enum ProcessInfoProperty
+ {
+ /// <summary></summary>
+ BasePriority,
+ /// <summary></summary>
+ ExitCode,
+ /// <summary></summary>
+ ExitTime,
+ /// <summary></summary>
+ Handle,
+ /// <summary></summary>
+ HandleCount,
+ /// <summary></summary>
+ HasExited,
+ /// <summary></summary>
+ Id,
+ /// <summary></summary>
+ MachineName,
+ /// <summary></summary>
+ MainModule,
+ /// <summary></summary>
+ MainWindowHandle,
+ /// <summary></summary>
+ MainWindowTitle,
+ /// <summary></summary>
+ MaxWorkingSet,
+ /// <summary></summary>
+ MinWorkingSet,
+ /// <summary></summary>
+ NonpagedSystemMemorySize,
+ /// <summary></summary>
+ NonpagedSystemMemorySize64,
+ /// <summary></summary>
+ PagedMemorySize,
+ /// <summary></summary>
+ PagedMemorySize64,
+ /// <summary></summary>
+ PagedSystemMemorySize,
+ /// <summary></summary>
+ PagedSystemMemorySize64,
+ /// <summary></summary>
+ PeakPagedMemorySize,
+ /// <summary></summary>
+ PeakPagedMemorySize64,
+ /// <summary></summary>
+ PeakVirtualMemorySize,
+ /// <summary></summary>
+ PeakVirtualMemorySize64,
+ /// <summary></summary>
+ PeakWorkingSet,
+ /// <summary></summary>
+ PeakWorkingSet64,
+ /// <summary></summary>
+ PriorityBoostEnabled,
+ /// <summary></summary>
+ PriorityClass,
+ /// <summary></summary>
+ PrivateMemorySize,
+ /// <summary></summary>
+ PrivateMemorySize64,
+ /// <summary></summary>
+ PrivilegedProcessorTime,
+ /// <summary></summary>
+ ProcessName,
+ /// <summary></summary>
+ Responding,
+ /// <summary></summary>
+ SessionId,
+ /// <summary></summary>
+ StartTime,
+ /// <summary></summary>
+ TotalProcessorTime,
+ /// <summary></summary>
+ UserProcessorTime,
+ /// <summary></summary>
+ VirtualMemorySize,
+ /// <summary></summary>
+ VirtualMemorySize64,
+ /// <summary></summary>
+ WorkingSet,
+ /// <summary></summary>
+ WorkingSet64
+ }
+
+ private ProcessInfoProperty _property = ProcessInfoProperty.Id;
+ private PropertyInfo _propertyInfo;
+ private Process _process;
+
+ /// <summary>
+ /// The property to retrieve.
+ /// </summary>
+ [DefaultValue("Id")]
+ [DefaultParameter]
+ public ProcessInfoProperty Property
+ {
+ get { return _property; }
+ set { _property = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the selected process information.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ if (_propertyInfo != null)
+ builder.Append(ApplyPadding(Convert.ToString(_propertyInfo.GetValue(_process, null), CultureInfo)));
+ }
+
+ /// <summary>
+ /// Initializes the layout renderer.
+ /// </summary>
+ public override void Initialize()
+ {
+ base.Initialize();
+ _propertyInfo = typeof(Process).GetProperty(Property.ToString());
+ if (_propertyInfo == null)
+ throw new ArgumentException("Property '" + _propertyInfo + "' not found in System.Diagnostics.Process");
+ _process = Process.GetCurrentProcess();
+ }
+
+ /// <summary>
+ /// Closes the layout renderer.
+ /// </summary>
+ public override void Close()
+ {
+ if (_process != null)
+ {
+ _process.Close();
+ _process = null;
+ }
+ base.Close();
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/ProcessName.cs b/src/NLog/LayoutRenderers/ProcessName.cs
new file mode 100644
index 0000000..a04fd44
--- /dev/null
+++ b/src/NLog/LayoutRenderers/ProcessName.cs
@@ -0,0 +1,103 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+
+using NLog.Internal;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The name of the current process.
+ /// </summary>
+ [LayoutRenderer("processname")]
+ public class ProcessNameLayoutRenderer: LayoutRenderer
+ {
+ private bool _fullName = false;
+
+ /// <summary>
+ /// Write the full path to the process executable.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool FullName
+ {
+ get { return _fullName; }
+ set { _fullName = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the current process name (optionally with a full path).
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ if (FullName)
+ {
+ builder.Append(ApplyPadding(ThreadIDHelper.Instance.CurrentProcessName));
+ }
+ else
+ {
+ builder.Append(ApplyPadding(ThreadIDHelper.Instance.CurrentProcessBaseName));
+ }
+ }
+
+ /// <summary>
+ /// Determines whether the value produced by the layout renderer
+ /// is fixed per current app-domain.
+ /// </summary>
+ /// <returns><see langword="true"/></returns>
+ protected internal override bool IsAppDomainFixed()
+ {
+ return true;
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/ProcessTime.cs b/src/NLog/LayoutRenderers/ProcessTime.cs
new file mode 100644
index 0000000..eff5a42
--- /dev/null
+++ b/src/NLog/LayoutRenderers/ProcessTime.cs
@@ -0,0 +1,90 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The process time in format HH:mm:ss.mmm
+ /// </summary>
+ [LayoutRenderer("processtime",UsingLogEventInfo=true,IgnoresPadding=true)]
+ public class ProcessTimeLayoutRenderer: LayoutRenderer
+ {
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the current process running time and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ TimeSpan ts = logEvent.TimeStamp - LogEventInfo.ZeroDate;
+ if (ts.Hours < 10)
+ builder.Append('0');
+ builder.Append(ts.Hours);
+ builder.Append(':');
+ if (ts.Minutes < 10)
+ builder.Append('0');
+ builder.Append(ts.Minutes);
+ builder.Append(':');
+ if (ts.Seconds < 10)
+ builder.Append('0');
+ builder.Append(ts.Seconds);
+ builder.Append('.');
+ if (ts.Milliseconds < 1000)
+ builder.Append('0');
+ if (ts.Milliseconds < 100)
+ builder.Append('0');
+ if (ts.Milliseconds < 10)
+ builder.Append('0');
+ builder.Append(ts.Milliseconds);
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/QPC.cs b/src/NLog/LayoutRenderers/QPC.cs
new file mode 100644
index 0000000..4a18553
--- /dev/null
+++ b/src/NLog/LayoutRenderers/QPC.cs
@@ -0,0 +1,213 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Globalization;
+using System.Security;
+using System.Runtime.InteropServices;
+
+using NLog.Config;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// High precision timer, based on the value returned from QueryPerformanceCounter() optionally converted to seconds.
+ /// </summary>
+ [LayoutRenderer("qpc")]
+ [SupportedRuntime(OS=RuntimeOS.Windows)]
+ [SupportedRuntime(OS=RuntimeOS.WindowsNT)]
+ [SupportedRuntime(OS=RuntimeOS.WindowsCE)]
+ public class QpcLayoutRenderer: LayoutRenderer
+ {
+ private bool _raw = false;
+ private bool _normalize = true;
+ private bool _diff = false;
+ private ulong _firstQpcValue = 0;
+ private ulong _lastQpcValue = 0;
+ private bool _first = true;
+ private double _frequency = 1;
+ private int _precision = 6;
+ private bool _alignDecimalPoint = true;
+
+ /// <summary>
+ /// Normalize the result by subtracting it from the result of the
+ /// first call (so that it's effectively zero-based).
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ private bool Normalize
+ {
+ get { return _normalize; }
+ set { _normalize = value; }
+ }
+
+ /// <summary>
+ /// Output the difference between the result of QueryPerformanceCounter
+ /// and the previous one.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ private bool Difference
+ {
+ get { return _diff; }
+ set { _diff = value; }
+ }
+
+ /// <summary>
+ /// Convert the result to seconds by dividing by the result of QueryPerformanceFrequency().
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool Seconds
+ {
+ get { return !_raw; }
+ set { _raw = !value; }
+ }
+
+ /// <summary>
+ /// Number of decimal digits to be included in output.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(4)]
+ public int Precision
+ {
+ get { return _precision; }
+ set { _precision = value; }
+ }
+
+ /// <summary>
+ /// Align decimal point (emit non-significant zeros)
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool AlignDecimalPoint
+ {
+ get { return _alignDecimalPoint; }
+ set { _alignDecimalPoint = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+
+ /// <summary>
+ /// Renders the ticks value of current time and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ ulong qpcValue;
+
+ if (!QueryPerformanceCounter(out qpcValue))
+ return;
+
+ if (_first)
+ {
+ lock (this)
+ {
+ if (_first)
+ {
+ ulong frequency;
+
+ QueryPerformanceFrequency(out frequency);
+ _frequency = (double)frequency;
+ _firstQpcValue = qpcValue;
+ _lastQpcValue = qpcValue;
+ _first = false;
+ }
+ }
+ }
+
+ ulong v = qpcValue;
+
+ if (Difference)
+ qpcValue -= _lastQpcValue;
+ else if (Normalize)
+ qpcValue -= _firstQpcValue;
+
+ _lastQpcValue = v;
+
+
+ string stringValue;
+
+ if (Seconds)
+ {
+ double val = Math.Round((double)qpcValue / _frequency, Precision);
+
+ stringValue = Convert.ToString(val, CultureInfo.InvariantCulture);
+ if (AlignDecimalPoint)
+ {
+ int p = stringValue.IndexOf('.');
+ if (p == -1)
+ {
+ stringValue += "." + new string('0', Precision);
+ }
+ else
+ {
+ stringValue += new string('0', Precision - (stringValue.Length - 1 - p));
+ }
+ }
+ }
+ else
+ {
+ stringValue = Convert.ToString(qpcValue);
+ }
+
+ builder.Append(ApplyPadding(stringValue));
+ }
+
+#if !NETCF
+ [DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity]
+#else
+ [DllImport("coredll.dll")]
+#endif
+ static extern bool QueryPerformanceCounter(out ulong lpPerformanceCount);
+
+#if !NETCF
+ [DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity]
+#else
+ [DllImport("coredll.dll")]
+#endif
+ static extern bool QueryPerformanceFrequency(out ulong lpPerformanceFrequency);
+ }
+}
diff --git a/src/NLog/LayoutRenderers/Rot13.cs b/src/NLog/LayoutRenderers/Rot13.cs
new file mode 100644
index 0000000..4c3f8d0
--- /dev/null
+++ b/src/NLog/LayoutRenderers/Rot13.cs
@@ -0,0 +1,134 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.IO;
+using NLog.Internal;
+using System.ComponentModel;
+using NLog.Config;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// Decodes text "encrypted" with ROT-13.
+ /// </summary>
+ /// <remarks>
+ /// See <a href="http://en.wikipedia.org/wiki/ROT13">http://en.wikipedia.org/wiki/ROT13</a>.
+ /// </remarks>
+ [LayoutRenderer("rot13")]
+ public class Rot13LayoutRenderer: LayoutRenderer
+ {
+ private Layout _inner;
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 30;
+ }
+
+ /// <summary>
+ /// The text to be decoded.
+ /// </summary>
+ [DefaultParameter]
+ public Layout Text
+ {
+ get { return _inner; }
+ set { _inner = value; }
+ }
+ /// <summary>
+ /// Renders the inner message, decrypts it with ROT-13 and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ string msg = _inner.GetFormattedMessage(logEvent);
+ builder.Append(ApplyPadding(DecodeRot13(msg)));
+ }
+
+
+ /// <summary>
+ /// Determines whether stack trace information should be gathered
+ /// during log event processing. By default it calls <see cref="NLog.Layout.NeedsStackTrace"/> on
+ /// <see cref="TargetWithLayout.CompiledLayout"/>.
+ /// </summary>
+ /// <returns>
+ /// 0 - don't include stack trace<br/>1 - include stack trace without source file information<br/>2 - include full stack trace
+ /// </returns>
+ protected internal override int NeedsStackTrace()
+ {
+ return Math.Max(base.NeedsStackTrace(), _inner.NeedsStackTrace());
+ }
+
+ /// <summary>
+ /// Encodes/Decodes ROT-13-encoded string.
+ /// </summary>
+ /// <param name="s">The string to be encoded/decoded</param>
+ /// <returns>Encoded/Decoded text</returns>
+ public static string DecodeRot13(string s)
+ {
+ char[] chars = s.ToCharArray();
+ for (int i = 0; i < chars.Length; ++i)
+ {
+ chars[i] = DecodeRot13Char(chars[i]);
+ }
+
+ return new string(chars);
+ }
+
+ private static char DecodeRot13Char(char c)
+ {
+ if (c >= 'A' && c <= 'M')
+ return (char)('N' + (c - 'A'));
+ if (c >= 'a' && c <= 'm')
+ return (char)('n' + (c - 'a'));
+ if (c >= 'N' && c <= 'Z')
+ return (char)('A' + (c - 'N'));
+ if (c >= 'n' && c <= 'z')
+ return (char)('a' + (c - 'n'));
+
+ return c;
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/ShortDate.cs b/src/NLog/LayoutRenderers/ShortDate.cs
new file mode 100644
index 0000000..fff906a
--- /dev/null
+++ b/src/NLog/LayoutRenderers/ShortDate.cs
@@ -0,0 +1,72 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Globalization;
+using System.Text;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The short date in a sortable format yyyy-MM-dd
+ /// </summary>
+ [LayoutRenderer("shortdate",UsingLogEventInfo=true)]
+ public class ShortDateLayoutRenderer: LayoutRenderer
+ {
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 10;
+ }
+
+ /// <summary>
+ /// Renders the current short date string (yyyy-MM-dd) and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ builder.Append(ApplyPadding(logEvent.TimeStamp.ToString("yyyy-MM-dd", CultureInfo)));
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/SpecialFolder.cs b/src/NLog/LayoutRenderers/SpecialFolder.cs
new file mode 100644
index 0000000..fff2000
--- /dev/null
+++ b/src/NLog/LayoutRenderers/SpecialFolder.cs
@@ -0,0 +1,145 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+using System;
+using System.Text;
+using System.IO;
+using NLog.Config;
+using System.ComponentModel;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// System special folder path (includes My Documents, My Music, Program Files, Desktop, and more)
+ /// </summary>
+ [LayoutRenderer("specialfolder")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class SpecialFolderLayoutRenderer : LayoutRenderer
+ {
+ private string _fileName = null;
+ private string _directoryName = null;
+ private System.Environment.SpecialFolder _folder;
+
+ /// <summary>
+ /// System special folder.
+ /// </summary>
+ /// <remarks>
+ /// Full list of options is available at <a href="http://msdn2.microsoft.com/en-us/system.environment.specialfolder.aspx">MSDN</a>.
+ /// The most common ones are:
+ /// <ul>
+ /// <li><b>ApplicationData</b> - roaming application data for current user.</li>
+ /// <li><b>CommonApplicationData</b> - application data for all users.</li>
+ /// <li><b>MyDocuments</b> - My Documents</li>
+ /// <li><b>DesktopDirectory</b> - Desktop directory</li>
+ /// <li><b>LocalApplicationData</b> - non roaming application data</li>
+ /// <li><b>Personal</b> - user profile directory</li>
+ /// <li><b>System</b> - System directory</li>
+ /// </ul>
+ /// </remarks>
+ [DefaultParameter]
+ public System.Environment.SpecialFolder Folder
+ {
+ get { return _folder; }
+ set { _folder = value; }
+ }
+
+ /// <summary>
+ /// The name of the file to be Path.Combine()'d with the directory name.
+ /// </summary>
+ public string File
+ {
+ get { return _fileName; }
+ set { _fileName = value; }
+ }
+
+ /// <summary>
+ /// The name of the directory to be Path.Combine()'d with the directory name.
+ /// </summary>
+ public string Dir
+ {
+ get { return _directoryName; }
+ set { _directoryName = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the directory where NLog is located and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ string baseDir = Environment.GetFolderPath(_folder);
+
+ if (File != null)
+ {
+ builder.Append(ApplyPadding(Path.Combine(baseDir, File)));
+ }
+ else if (Dir != null)
+ {
+ builder.Append(ApplyPadding(Path.Combine(baseDir, Dir)));
+ }
+ else
+ {
+ builder.Append(ApplyPadding(baseDir));
+ }
+ }
+
+ /// <summary>
+ /// Determines whether the value produced by the layout renderer
+ /// is fixed per current app-domain.
+ /// </summary>
+ /// <returns><see langword="true"/></returns>
+ protected internal override bool IsAppDomainFixed()
+ {
+ return true;
+ }
+ }
+}
+#endif
diff --git a/src/NLog/LayoutRenderers/StackTrace.cs b/src/NLog/LayoutRenderers/StackTrace.cs
new file mode 100644
index 0000000..b9a8427
--- /dev/null
+++ b/src/NLog/LayoutRenderers/StackTrace.cs
@@ -0,0 +1,186 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+using System;
+using System.Text;
+using System.Diagnostics;
+using System.Reflection;
+
+using NLog.Config;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// Format of the ${stacktrace} layout renderer output.
+ /// </summary>
+ public enum StackTraceFormat
+ {
+ /// <summary>
+ /// Raw format (multiline - as returned by StackFrame.ToString() method)
+ /// </summary>
+ Raw,
+
+ /// <summary>
+ /// Flat format (class and method names displayed in a single line)
+ /// </summary>
+ Flat,
+
+ /// <summary>
+ /// Detailed flat format (method signatures displayed in a single line)
+ /// </summary>
+ DetailedFlat,
+ }
+
+ /// <summary>
+ /// Stack trace renderer.
+ /// </summary>
+ [LayoutRenderer("stacktrace",UsingLogEventInfo=true,IgnoresPadding=true)]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class StackTraceLayoutRenderer: LayoutRenderer
+ {
+ private StackTraceFormat _format = StackTraceFormat.Flat;
+ private int _topFrames = 3;
+ private string _separator = " => ";
+
+ /// <summary>
+ /// The output format of the stack trace.
+ /// </summary>
+ [System.ComponentModel.DefaultValue("Flat")]
+ public StackTraceFormat Format
+ {
+ get { return _format; }
+ set { _format = value; }
+ }
+
+ /// <summary>
+ /// The number of top stack frames to be rendered.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(3)]
+ public int TopFrames
+ {
+ get { return _topFrames; }
+ set { _topFrames = value; }
+ }
+
+ /// <summary>
+ /// Stack frame separator string.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(" => ")]
+ public string Separator
+ {
+ get { return _separator; }
+ set { _separator = value; }
+ }
+
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 200;
+ }
+
+ /// <summary>
+ /// Checks whether the stack trace is requested.
+ /// </summary>
+ /// <returns>2 when the source file information is requested, 1 otherwise.</returns>
+ protected internal override int NeedsStackTrace()
+ {
+ return 2;
+ }
+
+ /// <summary>
+ /// Renders the call site and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ bool first = true;
+ int startingFrame = logEvent.UserStackFrameNumber + TopFrames - 1;
+ if (startingFrame >= logEvent.StackTrace.FrameCount)
+ startingFrame = logEvent.StackTrace.FrameCount - 1;
+
+ switch (Format)
+ {
+ case StackTraceFormat.Raw:
+ for (int i = startingFrame; i >= logEvent.UserStackFrameNumber; --i)
+ {
+ StackFrame f = logEvent.StackTrace.GetFrame(i);
+ builder.Append(f.ToString());
+ }
+ break;
+
+ case StackTraceFormat.Flat:
+ for (int i = startingFrame; i >= logEvent.UserStackFrameNumber; --i)
+ {
+ StackFrame f = logEvent.StackTrace.GetFrame(i);
+ if (!first)
+ builder.Append(_separator);
+
+ builder.Append(f.GetMethod().DeclaringType.Name);
+ builder.Append(".");
+ builder.Append(f.GetMethod().Name);
+ first = false;
+ }
+ break;
+
+ case StackTraceFormat.DetailedFlat:
+ for (int i = startingFrame; i >= logEvent.UserStackFrameNumber; --i)
+ {
+ StackFrame f = logEvent.StackTrace.GetFrame(i);
+ if (!first)
+ builder.Append(_separator);
+
+ builder.Append("[");
+ builder.Append(f.GetMethod());
+ builder.Append("]");
+ first = false;
+ }
+ break;
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/TempDir.cs b/src/NLog/LayoutRenderers/TempDir.cs
new file mode 100644
index 0000000..b6ee990
--- /dev/null
+++ b/src/NLog/LayoutRenderers/TempDir.cs
@@ -0,0 +1,123 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.IO;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// A temporary directory.
+ /// </summary>
+ [LayoutRenderer("tempdir")]
+ public class TempDirLayoutRenderer : LayoutRenderer
+ {
+ private string _fileName = null;
+ private string _directoryName = null;
+ private static string _tempDir;
+
+ static TempDirLayoutRenderer()
+ {
+ _tempDir = Path.GetTempPath();
+ }
+
+ /// <summary>
+ /// The name of the file to be Path.Combine()'d with the directory name.
+ /// </summary>
+ public string File
+ {
+ get { return _fileName; }
+ set { _fileName = value; }
+ }
+
+ /// <summary>
+ /// The name of the directory to be Path.Combine()'d with the directory name.
+ /// </summary>
+ public string Dir
+ {
+ get { return _directoryName; }
+ set { _directoryName = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the directory where NLog is located and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ string baseDir = _tempDir;
+
+ if (File != null)
+ {
+ builder.Append(ApplyPadding(Path.Combine(baseDir, File)));
+ }
+ else if (Dir != null)
+ {
+ builder.Append(ApplyPadding(Path.Combine(baseDir, Dir)));
+ }
+ else
+ {
+ builder.Append(ApplyPadding(baseDir));
+ }
+ }
+
+ /// <summary>
+ /// Determines whether the value produced by the layout renderer
+ /// is fixed per current app-domain.
+ /// </summary>
+ /// <returns><see langword="true"/></returns>
+ protected internal override bool IsAppDomainFixed()
+ {
+ return true;
+ }
+ }
+}
+
diff --git a/src/NLog/LayoutRenderers/ThreadID.cs b/src/NLog/LayoutRenderers/ThreadID.cs
new file mode 100644
index 0000000..cbf0439
--- /dev/null
+++ b/src/NLog/LayoutRenderers/ThreadID.cs
@@ -0,0 +1,74 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+
+using NLog.Internal;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The identifier of the current thread.
+ /// </summary>
+ [LayoutRenderer("threadid")]
+ public class ThreadIDLayoutRenderer: LayoutRenderer
+ {
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the current thread identifier and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ builder.Append(ApplyPadding(ThreadIDHelper.Instance.CurrentThreadID.ToString()));
+ }
+ }
+}
diff --git a/src/NLog/LayoutRenderers/ThreadName.cs b/src/NLog/LayoutRenderers/ThreadName.cs
new file mode 100644
index 0000000..da85f60
--- /dev/null
+++ b/src/NLog/LayoutRenderers/ThreadName.cs
@@ -0,0 +1,77 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+using System;
+using System.Text;
+
+using NLog.Config;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The name of the current thread.
+ /// </summary>
+ [LayoutRenderer("threadname")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class ThreadNameLayoutRenderer: LayoutRenderer
+ {
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the current thread name and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ builder.Append(ApplyPadding(System.Threading.Thread.CurrentThread.Name));
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/LayoutRenderers/Ticks.cs b/src/NLog/LayoutRenderers/Ticks.cs
new file mode 100644
index 0000000..6604b3b
--- /dev/null
+++ b/src/NLog/LayoutRenderers/Ticks.cs
@@ -0,0 +1,73 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Globalization;
+
+namespace NLog.LayoutRenderers
+{
+ /// <summary>
+ /// The Ticks value of current date and time.
+ /// </summary>
+ [LayoutRenderer("ticks",UsingLogEventInfo=true)]
+ public class TicksLayoutRenderer: LayoutRenderer
+ {
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+
+ /// <summary>
+ /// Renders the ticks value of current time and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ builder.Append(ApplyPadding(logEvent.TimeStamp.Ticks.ToString(Culture)));
+ }
+ }
+}
diff --git a/src/NLog/Layouts/CsvColumn.cs b/src/NLog/Layouts/CsvColumn.cs
new file mode 100644
index 0000000..d8d5697
--- /dev/null
+++ b/src/NLog/Layouts/CsvColumn.cs
@@ -0,0 +1,99 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Reflection;
+using System.Globalization;
+
+using NLog.Config;
+
+namespace NLog.Layouts
+{
+ /// <summary>
+ /// A column in the CSV
+ /// </summary>
+ public class CsvColumn
+ {
+ private Layout _compiledlayout;
+ private string _name;
+
+ /// <summary>
+ /// Constructs a new instance of <see cref="CsvColumn"/>.
+ /// </summary>
+ public CsvColumn()
+ {
+ }
+
+ /// <summary>
+ /// Constructs a new instance of <see cref="CsvColumn"/> and
+ /// initializes Name and Layout properties.
+ /// </summary>
+ public CsvColumn(string name, string layout)
+ {
+ Name = name;
+ Layout = layout;
+ }
+
+ /// <summary>
+ /// The name of the column.
+ /// </summary>
+ public string Name
+ {
+ get { return _name; }
+ set { _name = value; }
+ }
+
+ /// <summary>
+ /// The layout that should be written in the column.
+ /// </summary>
+ [AcceptsLayout]
+ [RequiredParameter]
+ public string Layout
+ {
+ get { return _compiledlayout.Text; }
+ set { _compiledlayout = new Layout(value); }
+ }
+
+ /// <summary>
+ /// The compiled layout that should be written in the column.
+ /// </summary>
+ public Layout CompiledLayout
+ {
+ get { return _compiledlayout; }
+ set { _compiledlayout = value; }
+ }
+ }
+}
diff --git a/src/NLog/Layouts/CsvColumnCollection.cs b/src/NLog/Layouts/CsvColumnCollection.cs
new file mode 100644
index 0000000..13e21e8
--- /dev/null
+++ b/src/NLog/Layouts/CsvColumnCollection.cs
@@ -0,0 +1,248 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Reflection;
+using System.Globalization;
+
+using NLog.Config;
+
+namespace NLog.Layouts
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A collection of elements of type CsvFileColumn
+ /// </summary>
+ public class CsvColumnCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the CsvFileColumnCollection class.
+ /// </summary>
+ public CsvColumnCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the CsvFileColumnCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new CsvFileColumnCollection.
+ /// </param>
+ public CsvColumnCollection(CsvColumn[]items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the CsvFileColumnCollection class, containing elements
+ /// copied from another instance of CsvFileColumnCollection
+ /// </summary>
+ /// <param name="items">
+ /// The CsvFileColumnCollection whose elements are to be added to the new CsvFileColumnCollection.
+ /// </param>
+ public CsvColumnCollection(CsvColumnCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this CsvFileColumnCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this CsvFileColumnCollection.
+ /// </param>
+ public virtual void AddRange(CsvColumn[]items)
+ {
+ foreach (CsvColumn item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another CsvFileColumnCollection to the end of this CsvFileColumnCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The CsvFileColumnCollection whose elements are to be added to the end of this CsvFileColumnCollection.
+ /// </param>
+ public virtual void AddRange(CsvColumnCollection items)
+ {
+ foreach (CsvColumn item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type CsvFileColumn to the end of this CsvFileColumnCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The CsvFileColumn to be added to the end of this CsvFileColumnCollection.
+ /// </param>
+ public virtual void Add(CsvColumn value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic CsvFileColumn value is in this CsvFileColumnCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The CsvFileColumn value to locate in this CsvFileColumnCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this CsvFileColumnCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(CsvColumn value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this CsvFileColumnCollection
+ /// </summary>
+ /// <param name="value">
+ /// The CsvFileColumn value to locate in the CsvFileColumnCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(CsvColumn value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the CsvFileColumnCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the CsvFileColumn is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The CsvFileColumn to insert.
+ /// </param>
+ public virtual void Insert(int index, CsvColumn value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the CsvFileColumn at the given index in this CsvFileColumnCollection.
+ /// </summary>
+ public virtual CsvColumn this[int index]
+ {
+ get { return (CsvColumn)this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific CsvFileColumn from this CsvFileColumnCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The CsvFileColumn value to remove from this CsvFileColumnCollection.
+ /// </param>
+ public virtual void Remove(CsvColumn value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by CsvFileColumnCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(CsvColumnCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public CsvColumn Current
+ {
+ get { return (CsvColumn)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (CsvColumn)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this CsvFileColumnCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual CsvColumnCollection.Enumerator GetEnumerator()
+ {
+ return new CsvColumnCollection.Enumerator(this);
+ }
+ }
+}
diff --git a/src/NLog/Layouts/CsvLayout.cs b/src/NLog/Layouts/CsvLayout.cs
new file mode 100644
index 0000000..9ffabe4
--- /dev/null
+++ b/src/NLog/Layouts/CsvLayout.cs
@@ -0,0 +1,490 @@
+using NLog.LayoutRenderers;
+using System.Text;
+using NLog.Config;
+using System.Globalization;
+using System;
+namespace NLog.Layouts
+{
+ /// <summary>
+ /// A specialized layout that renders CSV-formatted events.
+ /// </summary>
+ [Layout("CSVLayout")]
+ public class CsvLayout : ILayout, ILayoutWithHeaderAndFooter
+ {
+ /// <summary>
+ /// Specifies allowed column delimiters.
+ /// </summary>
+ public enum ColumnDelimiterMode
+ {
+ /// <summary>
+ /// Automatically detect from regional settings.
+ /// </summary>
+ Auto,
+
+ /// <summary>
+ /// Comma (ASCII 44)
+ /// </summary>
+ Comma,
+
+ /// <summary>
+ /// Semicolon (ASCII 59)
+ /// </summary>
+ Semicolon,
+
+ /// <summary>
+ /// Tab character (ASCII 9)
+ /// </summary>
+ Tab,
+
+ /// <summary>
+ /// Pipe character (ASCII 124)
+ /// </summary>
+ Pipe,
+
+ /// <summary>
+ /// Space character (ASCII 32)
+ /// </summary>
+ Space,
+
+ /// <summary>
+ /// Custom string, specified by the CustomDelimiter
+ /// </summary>
+ Custom,
+ }
+
+
+ private CsvColumnCollection _columns = new CsvColumnCollection();
+ private ColumnDelimiterMode _columnDelimiter = ColumnDelimiterMode.Auto;
+ private CsvQuotingMode _quotingMode = CsvQuotingMode.Auto;
+ private char[] _quotableCharacters;
+ private string _quoteChar = "\"";
+ private string _doubleQuoteChar;
+ private string _customColumnDelimiter;
+ private string _actualColumnDelimiter;
+ private ILayout _thisHeader;
+ private bool _withHeader = true;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CsvLayout"/> class.
+ /// </summary>
+ public CsvLayout()
+ {
+ _thisHeader = new CsvHeaderLayout(this);
+ }
+
+ /// <summary>
+ /// Array of parameters to be passed.
+ /// </summary>
+ [ArrayParameter(typeof(CsvColumn), "column")]
+ public CsvColumnCollection Columns
+ {
+ get { return _columns; }
+ }
+
+ /// <summary>
+ /// Whether CVS should include header.
+ /// </summary>
+ /// <value><c>true</c> if CVS should include header; otherwise, <c>false</c>.</value>
+ public bool WithHeader
+ {
+ get { return _withHeader; }
+ set { _withHeader = value; }
+ }
+
+ /// <summary>
+ /// Column delimiter.
+ /// </summary>
+ [System.ComponentModel.DefaultValue("Auto")]
+ public ColumnDelimiterMode Delimiter
+ {
+ get { return _columnDelimiter; }
+ set { _columnDelimiter = value; }
+ }
+
+ /// <summary>
+ /// Quoting mode.
+ /// </summary>
+ public CsvQuotingMode Quoting
+ {
+ get { return _quotingMode; }
+ set { _quotingMode = value; }
+ }
+
+ /// <summary>
+ /// Quote Character
+ /// </summary>
+ [System.ComponentModel.DefaultValue("\"")]
+ public string QuoteChar
+ {
+ get { return _quoteChar; }
+ set { _quoteChar = value; }
+ }
+
+ /// <summary>
+ /// Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom')
+ /// </summary>
+ public string CustomColumnDelimiter
+ {
+ get { return _customColumnDelimiter; }
+ set { _customColumnDelimiter = value; }
+ }
+
+ /// <summary>
+ /// Formats the log event for write.
+ /// </summary>
+ /// <param name="logEvent">The log event to be formatted.</param>
+ /// <returns>A string representation of the log event.</returns>
+ public string GetFormattedMessage(LogEventInfo logEvent)
+ {
+ string cachedValue = logEvent.GetCachedLayoutValue(this);
+ if (cachedValue != null)
+ return cachedValue;
+
+ StringBuilder sb = new StringBuilder();
+
+ bool first = true;
+
+ foreach (CsvColumn col in Columns)
+ {
+ if (!first)
+ {
+ sb.Append(_actualColumnDelimiter);
+ }
+
+ first = false;
+
+ bool useQuoting;
+ string text = col.CompiledLayout.GetFormattedMessage(logEvent);
+
+ switch (Quoting)
+ {
+ case CsvQuotingMode.Nothing:
+ useQuoting = false;
+ break;
+
+ case CsvQuotingMode.All:
+ useQuoting = true;
+ break;
+
+ default:
+ case CsvQuotingMode.Auto:
+ if (text.IndexOfAny(_quotableCharacters) >= 0)
+ useQuoting = true;
+ else
+ useQuoting = false;
+ break;
+ }
+
+ if (useQuoting)
+ sb.Append(QuoteChar);
+
+ if (useQuoting)
+ sb.Append(text.Replace(QuoteChar, _doubleQuoteChar));
+ else
+ sb.Append(text);
+
+ if (useQuoting)
+ sb.Append(QuoteChar);
+ }
+
+ logEvent.AddCachedLayoutValue(this, sb.ToString());
+ return sb.ToString();
+ }
+
+ /// <summary>
+ /// Initializes the layout.
+ /// </summary>
+ public void Initialize()
+ {
+ switch (Delimiter)
+ {
+ case ColumnDelimiterMode.Auto:
+ _actualColumnDelimiter = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
+ break;
+
+ case ColumnDelimiterMode.Comma:
+ _actualColumnDelimiter = ",";
+ break;
+
+ case ColumnDelimiterMode.Semicolon:
+ _actualColumnDelimiter = ";";
+ break;
+
+ case ColumnDelimiterMode.Pipe:
+ _actualColumnDelimiter = "|";
+ break;
+
+ case ColumnDelimiterMode.Tab:
+ _actualColumnDelimiter = "\t";
+ break;
+
+ case ColumnDelimiterMode.Space:
+ _actualColumnDelimiter = " ";
+ break;
+
+ case ColumnDelimiterMode.Custom:
+ _actualColumnDelimiter = _customColumnDelimiter;
+ break;
+ }
+ _quotableCharacters = (QuoteChar + "\r\n" + _actualColumnDelimiter).ToCharArray();
+ _doubleQuoteChar = _quoteChar + _quoteChar;
+
+ foreach (CsvColumn c in Columns)
+ {
+ c.CompiledLayout.Initialize();
+ }
+ }
+
+ /// <summary>
+ /// Returns the value indicating whether a stack trace and/or the source file
+ /// information should be gathered during layout processing.
+ /// </summary>
+ /// <returns>0 - don't include stack trace<br/>1 - include stack trace without source file information<br/>2 - include full stack trace</returns>
+ public int NeedsStackTrace()
+ {
+ int nst = 0;
+
+ foreach (CsvColumn cc in _columns)
+ {
+ nst = Math.Max(nst, cc.CompiledLayout.NeedsStackTrace());
+ }
+ return nst;
+ }
+
+ /// <summary>
+ /// Returns the value indicating whether this layout includes any volatile
+ /// layout renderers.
+ /// </summary>
+ /// <returns><see langword="true" /> when the layout includes at least
+ /// one volatile renderer, <see langword="false"/> otherwise.</returns>
+ /// <remarks>
+ /// Volatile layout renderers are dependent on information not contained
+ /// in <see cref="LogEventInfo"/> (such as thread-specific data, MDC data, NDC data).
+ /// </remarks>
+ public bool IsVolatile()
+ {
+ foreach (CsvColumn cc in _columns)
+ {
+ if (cc.CompiledLayout.IsVolatile())
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Precalculates the layout for the specified log event and stores the result
+ /// in per-log event cache.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ /// <remarks>
+ /// Calling this method enables you to store the log event in a buffer
+ /// and/or potentially evaluate it in another thread even though the
+ /// layout may contain thread-dependent renderer.
+ /// </remarks>
+ public void Precalculate(LogEventInfo logEvent)
+ {
+ GetFormattedMessage(logEvent);
+ }
+
+ /// <summary>
+ /// Closes the layout.
+ /// </summary>
+ public void Close()
+ {
+ foreach (CsvColumn c in Columns)
+ c.CompiledLayout.Close();
+ }
+
+ /// <summary>
+ /// Gets the header.
+ /// </summary>
+ /// <param name="logEvent">The log event to be formatted.</param>
+ /// <returns>A string representation of the log event.</returns>
+ public string GetHeader(LogEventInfo logEvent)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ bool first = true;
+
+ foreach (CsvColumn col in Columns)
+ {
+ if (!first)
+ {
+ sb.Append(_actualColumnDelimiter);
+ }
+
+ first = false;
+
+ bool useQuoting;
+ string text = col.Name;
+
+ switch (Quoting)
+ {
+ case CsvQuotingMode.Nothing:
+ useQuoting = false;
+ break;
+
+ case CsvQuotingMode.All:
+ useQuoting = true;
+ break;
+
+ default:
+ case CsvQuotingMode.Auto:
+ if (text.IndexOfAny(_quotableCharacters) >= 0)
+ useQuoting = true;
+ else
+ useQuoting = false;
+ break;
+ }
+
+ if (useQuoting)
+ sb.Append(QuoteChar);
+
+ if (useQuoting)
+ sb.Append(text.Replace(QuoteChar, _doubleQuoteChar));
+ else
+ sb.Append(text);
+
+ if (useQuoting)
+ sb.Append(QuoteChar);
+ }
+
+ return sb.ToString();
+ }
+
+ /// <summary>
+ /// Main layout (can be repeated multiple times)
+ /// </summary>
+ /// <value></value>
+ public ILayout Layout
+ {
+ get { return this; }
+ set { throw new Exception("Cannot modify the layout of CsvLayout"); }
+ }
+
+ /// <summary>
+ /// Header
+ /// </summary>
+ /// <value></value>
+ public ILayout Header
+ {
+ get
+ {
+ if (WithHeader)
+ return _thisHeader;
+ else
+ return null;
+ }
+ set { throw new Exception("Cannot modify the header of CsvLayout"); }
+ }
+
+ /// <summary>
+ /// Footer
+ /// </summary>
+ /// <remarks>CSV has no footer.</remarks>
+ public ILayout Footer
+ {
+ get { return null; }
+ set { throw new Exception("Cannot modify the footer of CsvLayout"); }
+ }
+
+ class CsvHeaderLayout : ILayout
+ {
+ private CsvLayout _parent;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CsvHeaderLayout"/> class.
+ /// </summary>
+ /// <param name="parent">The parent.</param>
+ public CsvHeaderLayout(CsvLayout parent)
+ {
+ _parent = parent;
+ }
+
+ /// <summary>
+ /// Renders the layout for the specified logging event by invoking layout renderers.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ /// <returns>The rendered layout.</returns>
+ public string GetFormattedMessage(LogEventInfo logEvent)
+ {
+ return _parent.GetHeader(logEvent);
+ }
+
+ /// <summary>
+ /// Returns the value indicating whether a stack trace and/or the source file
+ /// information should be gathered during layout processing.
+ /// </summary>
+ /// <returns>
+ /// 0 - don't include stack trace<br/>1 - include stack trace without source file information<br/>2 - include full stack trace
+ /// </returns>
+ public int NeedsStackTrace()
+ {
+ return 0;
+ }
+
+ /// <summary>
+ /// Returns the value indicating whether this layout includes any volatile
+ /// layout renderers.
+ /// </summary>
+ /// <returns>
+ /// <see langword="true"/> when the layout includes at least
+ /// one volatile renderer, <see langword="false"/> otherwise.
+ /// </returns>
+ /// <remarks>
+ /// Volatile layout renderers are dependent on information not contained
+ /// in <see cref="LogEventInfo"/> (such as thread-specific data, MDC data, NDC data).
+ /// </remarks>
+ public bool IsVolatile()
+ {
+ return false;
+ }
+
+ /// <summary>
+ /// Precalculates the layout for the specified log event and stores the result
+ /// in per-log event cache.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ /// <remarks>
+ /// Calling this method enables you to store the log event in a buffer
+ /// and/or potentially evaluate it in another thread even though the
+ /// layout may contain thread-dependent renderer.
+ /// </remarks>
+ public void Precalculate(LogEventInfo logEvent)
+ {
+ }
+
+ /// <summary>
+ /// Initializes the layout.
+ /// </summary>
+ public void Initialize()
+ {
+ }
+
+ /// <summary>
+ /// Closes the layout.
+ /// </summary>
+ public void Close()
+ {
+ }
+
+ /// <summary>
+ /// Add this layout and all sub-layouts to the specified collection..
+ /// </summary>
+ /// <param name="layouts">The collection of layouts.</param>
+ public void PopulateLayouts(LayoutCollection layouts)
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ }
+
+ /// <summary>
+ /// Add this layout and all sub-layouts to the specified collection..
+ /// </summary>
+ /// <param name="layouts">The collection of layouts.</param>
+ public void PopulateLayouts(LayoutCollection layouts)
+ {
+ layouts.Add(this);
+ }
+ }
+}
diff --git a/src/NLog/Layouts/CsvQuotingMode.cs b/src/NLog/Layouts/CsvQuotingMode.cs
new file mode 100644
index 0000000..6b6d0e2
--- /dev/null
+++ b/src/NLog/Layouts/CsvQuotingMode.cs
@@ -0,0 +1,67 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Reflection;
+using System.Globalization;
+
+using NLog.Config;
+
+namespace NLog.Layouts
+{
+ /// <summary>
+ /// Specifies allowes CSV quoting modes.
+ /// </summary>
+ public enum CsvQuotingMode
+ {
+ /// <summary>
+ /// Quote all column.
+ /// </summary>
+ All,
+
+ /// <summary>
+ /// Quote nothing.
+ /// </summary>
+ Nothing,
+
+ /// <summary>
+ /// Quote only whose values contain the quote symbol or
+ /// the separator.
+ /// </summary>
+ Auto
+ }
+
+}
diff --git a/src/NLog/Layouts/LayoutWithHeaderAndFooter.cs b/src/NLog/Layouts/LayoutWithHeaderAndFooter.cs
new file mode 100644
index 0000000..bd74a67
--- /dev/null
+++ b/src/NLog/Layouts/LayoutWithHeaderAndFooter.cs
@@ -0,0 +1,166 @@
+using NLog.LayoutRenderers;
+using System.Text;
+using NLog.Config;
+using System.Globalization;
+using System;
+
+namespace NLog.Layouts
+{
+ /// <summary>
+ /// A specialized layout that supports header and footer.
+ /// </summary>
+ [Layout("LayoutWithHeaderAndFooter")]
+ public class LayoutWithHeaderAndFooter : ILayout, ILayoutWithHeaderAndFooter
+ {
+ private ILayout _header = null;
+ private ILayout _footer = null;
+ private ILayout _layout = null;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="LayoutWithHeaderAndFooter"/> class.
+ /// </summary>
+ public LayoutWithHeaderAndFooter()
+ {
+ }
+
+ /// <summary>
+ /// Main layout (can be repeated multiple times)
+ /// </summary>
+ /// <value></value>
+ public ILayout Layout
+ {
+ get { return _layout; }
+ set { _layout = value; }
+ }
+
+ /// <summary>
+ /// Header
+ /// </summary>
+ /// <value></value>
+ public ILayout Header
+ {
+ get { return _header; }
+ set { _header = value; }
+ }
+
+ /// <summary>
+ /// Footer
+ /// </summary>
+ /// <value></value>
+ public ILayout Footer
+ {
+ get { return _footer; }
+ set { _footer = value; }
+ }
+
+ /// <summary>
+ /// Renders the layout for the specified logging event by invoking layout renderers.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ /// <returns>The rendered layout.</returns>
+ public string GetFormattedMessage(LogEventInfo logEvent)
+ {
+ return _layout.GetFormattedMessage(logEvent);
+ }
+
+ /// <summary>
+ /// Returns the value indicating whether a stack trace and/or the source file
+ /// information should be gathered during layout processing.
+ /// </summary>
+ /// <returns>
+ /// 0 - don't include stack trace<br/>1 - include stack trace without source file information<br/>2 - include full stack trace
+ /// </returns>
+ public int NeedsStackTrace()
+ {
+ int max = Layout.NeedsStackTrace();
+ if (Header != null)
+ max = Math.Max(max, Header.NeedsStackTrace());
+ if (Footer != null)
+ max = Math.Max(max, Footer.NeedsStackTrace());
+ return max;
+ }
+
+ /// <summary>
+ /// Returns the value indicating whether this layout includes any volatile
+ /// layout renderers.
+ /// </summary>
+ /// <returns>
+ /// <see langword="true"/> when the layout includes at least
+ /// one volatile renderer, <see langword="false"/> otherwise.
+ /// </returns>
+ /// <remarks>
+ /// Volatile layout renderers are dependent on information not contained
+ /// in <see cref="LogEventInfo"/> (such as thread-specific data, MDC data, NDC data).
+ /// </remarks>
+ public bool IsVolatile()
+ {
+ if (Layout.IsVolatile())
+ return true;
+
+ if (Header != null && Header.IsVolatile())
+ return true;
+
+ if (Footer != null && Footer.IsVolatile())
+ return true;
+
+ return false;
+ }
+
+ /// <summary>
+ /// Precalculates the layout for the specified log event and stores the result
+ /// in per-log event cache.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ /// <remarks>
+ /// Calling this method enables you to store the log event in a buffer
+ /// and/or potentially evaluate it in another thread even though the
+ /// layout may contain thread-dependent renderer.
+ /// </remarks>
+ public void Precalculate(LogEventInfo logEvent)
+ {
+ Layout.Precalculate(logEvent);
+ if (Header != null)
+ Header.Precalculate(logEvent);
+ if (Footer != null)
+ Footer.Precalculate(logEvent);
+ }
+
+ /// <summary>
+ /// Initializes the layout.
+ /// </summary>
+ public void Initialize()
+ {
+ Layout.Initialize();
+ if (Header != null)
+ Header.Initialize();
+ if (Footer != null)
+ Footer.Initialize();
+ }
+
+ /// <summary>
+ /// Closes the layout.
+ /// </summary>
+ public void Close()
+ {
+ Layout.Close();
+ if (Header != null)
+ Header.Close();
+ if (Footer != null)
+ Footer.Close();
+ }
+
+ /// <summary>
+ /// Add this layout and all sub-layouts to the specified collection..
+ /// </summary>
+ /// <param name="layouts">The collection of layouts.</param>
+ public void PopulateLayouts(LayoutCollection layouts)
+ {
+ layouts.Add(this);
+ Layout.PopulateLayouts(layouts);
+ if (Header != null)
+ Header.PopulateLayouts(layouts);
+ if (Footer != null)
+ Footer.PopulateLayouts(layouts);
+ }
+ }
+}
diff --git a/src/NLog/Layouts/Log4JXmlEventLayout.cs b/src/NLog/Layouts/Log4JXmlEventLayout.cs
new file mode 100644
index 0000000..d8e621a
--- /dev/null
+++ b/src/NLog/Layouts/Log4JXmlEventLayout.cs
@@ -0,0 +1,102 @@
+using NLog.LayoutRenderers;
+using System.Text;
+namespace NLog.Layouts
+{
+ /// <summary>
+ /// A specialized layout that renders Log4j-compatible XML events.
+ /// </summary>
+ [Layout("Log4JXmlEventLayout")]
+ public class Log4JXmlEventLayout : ILayout
+ {
+ private Log4JXmlEventLayoutRenderer _renderer = new Log4JXmlEventLayoutRenderer();
+
+ /// <summary>
+ /// Returns the <see cref="Log4JXmlEventLayoutRenderer"/> instance that renders log events.
+ /// </summary>
+ public Log4JXmlEventLayoutRenderer Renderer
+ {
+ get { return _renderer; }
+ }
+
+ /// <summary>
+ /// Renders the layout for the specified logging event by invoking layout renderers.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ /// <returns>The rendered layout.</returns>
+ public string GetFormattedMessage(LogEventInfo logEvent)
+ {
+ string cachedValue = logEvent.GetCachedLayoutValue(this);
+ if (cachedValue != null)
+ return cachedValue;
+
+ StringBuilder sb = new StringBuilder(_renderer.GetEstimatedBufferSize(logEvent));
+
+ _renderer.Append(sb, logEvent);
+ logEvent.AddCachedLayoutValue(this, sb.ToString());
+ return sb.ToString();
+ }
+
+ /// <summary>
+ /// Returns the value indicating whether a stack trace and/or the source file
+ /// information should be gathered during layout processing.
+ /// </summary>
+ /// <returns>0 - don't include stack trace<br/>1 - include stack trace without source file information<br/>2 - include full stack trace</returns>
+ public int NeedsStackTrace()
+ {
+ return _renderer.NeedsStackTrace();
+ }
+
+ /// <summary>
+ /// Returns the value indicating whether this layout includes any volatile
+ /// layout renderers.
+ /// </summary>
+ /// <returns><see langword="true" /> when the layout includes at least
+ /// one volatile renderer, <see langword="false"/> otherwise.</returns>
+ /// <remarks>
+ /// Volatile layout renderers are dependent on information not contained
+ /// in <see cref="LogEventInfo"/> (such as thread-specific data, MDC data, NDC data).
+ /// </remarks>
+ public bool IsVolatile()
+ {
+ return _renderer.IsVolatile();
+ }
+
+ /// <summary>
+ /// Precalculates the layout for the specified log event and stores the result
+ /// in per-log event cache.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ /// <remarks>
+ /// Calling this method enables you to store the log event in a buffer
+ /// and/or potentially evaluate it in another thread even though the
+ /// layout may contain thread-dependent renderer.
+ /// </remarks>
+ public void Precalculate(LogEventInfo logEvent)
+ {
+ GetFormattedMessage(logEvent);
+ }
+
+ /// <summary>
+ /// Initializes the layout.
+ /// </summary>
+ public void Initialize()
+ {
+ }
+
+ /// <summary>
+ /// Closes the layout.
+ /// </summary>
+ public void Close()
+ {
+ }
+
+ /// <summary>
+ /// Add this layout and all sub-layouts to the specified collection..
+ /// </summary>
+ /// <param name="layouts">The collection of layouts.</param>
+ public void PopulateLayouts(LayoutCollection layouts)
+ {
+ layouts.Add(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/NLog/LogEventInfo.cs b/src/NLog/LogEventInfo.cs
new file mode 100644
index 0000000..88b1879
--- /dev/null
+++ b/src/NLog/LogEventInfo.cs
@@ -0,0 +1,366 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Globalization;
+using System.Diagnostics;
+using System.Threading;
+using System.Reflection;
+
+using System.Collections;
+using System.Collections.Specialized;
+
+namespace NLog
+{
+ /// <summary>
+ /// Represents the logging event.
+ /// </summary>
+ public class LogEventInfo
+ {
+ /// <summary>
+ /// The date of the first log event created.
+ /// </summary>
+ public static readonly DateTime ZeroDate = DateTime.Now;
+
+ private static int _globalSequenceID = 0;
+
+ private DateTime _timeStamp;
+ private LogLevel _level;
+ private string _loggerName;
+ private string _message;
+ private string _formattedMessage;
+ private Exception _exception;
+ private object[] _parameters;
+ private IFormatProvider _formatProvider;
+ private IDictionary _layoutCache;
+ private IDictionary _eventContext;
+ private int _sequenceID;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="LogEventInfo"/>.
+ /// </summary>
+ public LogEventInfo()
+ {
+ }
+
+ /// <summary>
+ /// Creates the null event.
+ /// </summary>
+ /// <returns></returns>
+ public static LogEventInfo CreateNullEvent()
+ {
+ return new LogEventInfo(LogLevel.Off, "", "");
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="LogEventInfo"/> and assigns its fields.
+ /// </summary>
+ /// <param name="level">Log level</param>
+ /// <param name="loggerName">Logger name</param>
+ /// <param name="message">Log message including parameter placeholders</param>
+ public LogEventInfo(LogLevel level, string loggerName, string message)
+ : this(level, loggerName, null, message, null, null)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="LogEventInfo"/> and assigns its fields.
+ /// </summary>
+ /// <param name="level">Log level</param>
+ /// <param name="loggerName">Logger name</param>
+ /// <param name="formatProvider"><see cref="IFormatProvider"/> object</param>
+ /// <param name="message">Log message including parameter placeholders</param>
+ /// <param name="parameters">Parameter array.</param>
+ public LogEventInfo(LogLevel level, string loggerName, IFormatProvider formatProvider, string message, object[] parameters)
+ : this(level, loggerName, formatProvider, message, parameters, null)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="LogEventInfo"/> and assigns its fields.
+ /// </summary>
+ /// <param name="level">Log level</param>
+ /// <param name="loggerName">Logger name</param>
+ /// <param name="formatProvider"><see cref="IFormatProvider"/> object</param>
+ /// <param name="message">Log message including parameter placeholders</param>
+ /// <param name="parameters">Parameter array.</param>
+ /// <param name="exception">Exception information.</param>
+ public LogEventInfo(LogLevel level, string loggerName, IFormatProvider formatProvider, string message, object[] parameters, Exception exception)
+ {
+ _timeStamp = CurrentTimeGetter.Now;
+ _level = level;
+ _loggerName = loggerName;
+ _message = message;
+ _parameters = parameters;
+ _formatProvider = formatProvider;
+ _exception = exception;
+ _layoutCache = null;
+ _sequenceID = Interlocked.Increment(ref _globalSequenceID);
+ _formattedMessage = null;
+
+ if (NeedToPreformatMessage(parameters))
+ CalcFormattedMessage();
+
+#if !NETCF
+ _stackTrace = null;
+ _userStackFrame = 0;
+#endif
+ }
+
+ /// <summary>
+ /// Gets or sets the timestamp of the logging event.
+ /// </summary>
+ public DateTime TimeStamp
+ {
+ get { return _timeStamp; }
+ set { _timeStamp = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the level of the logging event.
+ /// </summary>
+ public LogLevel Level
+ {
+ get { return _level; }
+ set { _level = value; }
+ }
+
+#if !NETCF
+ private StackTrace _stackTrace;
+ private int _userStackFrame;
+
+ /// <summary>
+ /// Returns true if stack trace has been set for this event.
+ /// </summary>
+ public bool HasStackTrace
+ {
+ get { return _stackTrace != null; }
+ }
+
+ internal void SetStackTrace(StackTrace stackTrace, int userStackFrame)
+ {
+ _stackTrace = stackTrace;
+ _userStackFrame = userStackFrame;
+ }
+
+ /// <summary>
+ /// Gets the stack frame of the method that did the logging.
+ /// </summary>
+ public StackFrame UserStackFrame
+ {
+ get { return (_stackTrace != null) ? _stackTrace.GetFrame(_userStackFrame): null; }
+ }
+
+ /// <summary>
+ /// Gets the number index of the stack frame that represents the user
+ /// code (not the NLog code)
+ /// </summary>
+ public int UserStackFrameNumber
+ {
+ get { return _userStackFrame; }
+ }
+
+ /// <summary>
+ /// Gets the entire stack trace.
+ /// </summary>
+ public StackTrace StackTrace
+ {
+ get { return _stackTrace; }
+ }
+#endif
+ /// <summary>
+ /// Gets or sets the exception information.
+ /// </summary>
+ public Exception Exception
+ {
+ get { return _exception; }
+ set { _exception = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the logger name.
+ /// </summary>
+ public string LoggerName
+ {
+ get { return _loggerName; }
+ set { _loggerName = value; }
+ }
+
+ /// <summary>
+ /// Gets the logger short name.
+ /// </summary>
+ public string LoggerShortName
+ {
+ get
+ {
+ int lastDot = _loggerName.LastIndexOf('.');
+ if (lastDot >= 0)
+ return _loggerName.Substring(lastDot + 1);
+ else
+ return _loggerName;
+ }
+ }
+
+ /// <summary>
+ /// Gets the raw log message including any parameter placeholders.
+ /// </summary>
+ public string Message
+ {
+ get { return _message; }
+ set { _message = value; }
+ }
+
+ /// <summary>
+ /// Gets the parameter values or <see langword="null" /> if no parameters have
+ /// been specified.
+ /// </summary>
+ public object[] Parameters
+ {
+ get { return _parameters; }
+ set { _parameters = value; }
+ }
+
+ /// <summary>
+ /// Gets the format provider that was provided while logging or <see langword="null" />
+ /// when no formatProvider was specified.
+ /// </summary>
+ public IFormatProvider FormatProvider
+ {
+ get { return _formatProvider; }
+ set { _formatProvider = value; }
+ }
+
+ /// <summary>
+ /// Returns the formatted message.
+ /// </summary>
+ public string FormattedMessage
+ {
+ get
+ {
+ if (_formattedMessage == null)
+ CalcFormattedMessage();
+
+ return _formattedMessage;
+ }
+ }
+
+ /// <summary>
+ /// Gets the dictionary of per-event context properties.
+ /// </summary>
+ public IDictionary Context
+ {
+ get
+ {
+ if (_eventContext == null)
+ _eventContext = new HybridDictionary();
+ return _eventContext;
+ }
+ }
+
+ /// <summary>
+ /// The unique identifier of log event which is automatically generated
+ /// and monotonously increasing.
+ /// </summary>
+ public int SequenceID
+ {
+ get { return _sequenceID; }
+ }
+
+ internal string GetCachedLayoutValue(ILayout layout)
+ {
+ if (_layoutCache == null)
+ return null;
+ string result = (string)_layoutCache[layout];
+ return result;
+ }
+
+ internal void AddCachedLayoutValue(ILayout layout, string value)
+ {
+ if (_layoutCache == null)
+ _layoutCache = new HybridDictionary();
+ _layoutCache[layout] = value;
+ }
+
+ private void CalcFormattedMessage()
+ {
+ _formattedMessage = _message;
+
+ if (_parameters == null || _parameters.Length == 0)
+ return;
+
+ if (_formatProvider != null)
+ _formattedMessage = String.Format(_formatProvider, _message, _parameters);
+ else
+ _formattedMessage = String.Format(_message, _parameters);
+ }
+
+ private bool NeedToPreformatMessage(object[] parameters)
+ {
+ // we need to preformat message if it contains any parameters which could possibly
+ // do logging in their ToString()
+ if (parameters == null)
+ return false;
+
+ if (parameters.Length == 0)
+ return false;
+
+ if (parameters.Length > 3)
+ {
+ // too many parameters, too costly to check
+ return true;
+ }
+
+ if (!IsSafeToDeferFormatting(parameters[0]))
+ return true;
+ if (parameters.Length >= 2)
+ {
+ if (!IsSafeToDeferFormatting(parameters[1]))
+ return true;
+ }
+ if (parameters.Length >= 3)
+ {
+ if (!IsSafeToDeferFormatting(parameters[2]))
+ return true;
+ }
+ return false;
+ }
+
+ private bool IsSafeToDeferFormatting(object value)
+ {
+ if (value == null)
+ return true;
+
+ return (value.GetType().IsPrimitive || value is string);
+ }
+ }
+}
diff --git a/src/NLog/LogFactory.cs b/src/NLog/LogFactory.cs
new file mode 100644
index 0000000..f351c95
--- /dev/null
+++ b/src/NLog/LogFactory.cs
@@ -0,0 +1,714 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using System.Diagnostics;
+using System.Security;
+using System.Text;
+using System.Globalization;
+using System.Runtime.CompilerServices;
+
+using NLog.Config;
+using NLog.Internal;
+using NLog.Targets;
+
+namespace NLog
+{
+ /// <summary>
+ /// Represents a method that's invoked each time a logging configuration changes.
+ /// </summary>
+ public delegate void LoggingConfigurationChanged(LoggingConfiguration oldConfig, LoggingConfiguration newConfig);
+
+ /// <summary>
+ /// Represents a method that's invoked each time a logging configuration gets reloaded
+ /// to signal either success or failure.
+ /// </summary>
+ public delegate void LoggingConfigurationReloaded(bool succeeded, Exception ex);
+
+ /// <summary>
+ /// Creates and manages instances of <see cref="T:NLog.Logger" /> objects.
+ /// </summary>
+ public class LogFactory
+ {
+ private Hashtable _loggerCache = new Hashtable();
+ private LoggingConfiguration _config;
+ private LogLevel _globalThreshold = LogLevel.MinLevel;
+ private bool _configLoaded = false;
+ private bool _throwExceptions = false;
+ private int _logsEnabled = 0;
+
+ /// <summary>
+ /// Occurs when logging <see cref="Configuration" /> changes.
+ /// </summary>
+ public event LoggingConfigurationChanged ConfigurationChanged;
+
+#if !NETCF
+ /// <summary>
+ /// Occurs when logging <see cref="Configuration" /> gets reloaded.
+ /// </summary>
+ public event LoggingConfigurationReloaded ConfigurationReloaded;
+#endif
+ /// <summary>
+ /// Specified whether NLog should throw exceptions. By default exceptions
+ /// are not thrown under any circumstances.
+ /// </summary>
+ public bool ThrowExceptions
+ {
+ get { return _throwExceptions; }
+ set { _throwExceptions = value; }
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="LogFactory"/>
+ /// </summary>
+ public LogFactory()
+ {
+#if !NETCF
+ _watcher = new MultiFileWatcher(new EventHandler(ConfigFileChanged));
+#endif
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="LogFactory"/> and sets the initial configuration.
+ /// </summary>
+ public LogFactory(LoggingConfiguration config) : this()
+ {
+ Configuration = config;
+ }
+
+ /// <summary>
+ /// Creates a logger that discards all log messages.
+ /// </summary>
+ /// <returns></returns>
+ public Logger CreateNullLogger()
+ {
+ TargetWithFilterChain[]targetsByLevel = new TargetWithFilterChain[LogLevel.MaxLevel.Ordinal + 1];
+ Logger newLogger = new Logger();
+ newLogger.Initialize("", new LoggerConfiguration(targetsByLevel), this);
+ return newLogger;
+ }
+
+#if !NETCF
+ /// <summary>
+ /// Gets the logger named after the currently-being-initialized class.
+ /// </summary>
+ /// <returns>The logger.</returns>
+ /// <remarks>This is a slow-running method.
+ /// Make sure you're not doing this in a loop.</remarks>
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public Logger GetCurrentClassLogger()
+ {
+ StackFrame frame = new StackFrame(1, false);
+
+ return GetLogger(frame.GetMethod().DeclaringType.FullName);
+ }
+
+ /// <summary>
+ /// Gets the logger named after the currently-being-initialized class.
+ /// </summary>
+ /// <param name="loggerType">type of the logger to create. The type must inherit from NLog.Logger</param>
+ /// <returns>The logger.</returns>
+ /// <remarks>This is a slow-running method.
+ /// Make sure you're not doing this in a loop.</remarks>
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public Logger GetCurrentClassLogger(Type loggerType)
+ {
+ StackFrame frame = new StackFrame(1, false);
+
+ return GetLogger(frame.GetMethod().DeclaringType.FullName, loggerType);
+ }
+#endif
+
+ class LoggerCacheKey
+ {
+ private Type _loggerConcreteType;
+ private string _name;
+
+ public LoggerCacheKey(Type loggerConcreteType, string name)
+ {
+ _loggerConcreteType = loggerConcreteType;
+ _name = name;
+ }
+
+ public override int GetHashCode()
+ {
+ return _loggerConcreteType.GetHashCode() ^ _name.GetHashCode();
+ }
+
+ public override bool Equals(object o)
+ {
+ LoggerCacheKey lck2 = (LoggerCacheKey)o;
+ if (lck2 == null)
+ return false;
+
+ return (ConcreteType == lck2.ConcreteType) && (lck2.Name == Name);
+ }
+
+ public Type ConcreteType
+ {
+ get { return _loggerConcreteType; }
+ }
+
+ public string Name
+ {
+ get { return _name; }
+ }
+ }
+
+ private Logger GetLogger(LoggerCacheKey cacheKey)
+ {
+ lock(this)
+ {
+ Logger l = (Logger)_loggerCache[cacheKey];
+ if (l != null)
+ return l;
+
+ //Activator.CreateInstance(cacheKey.ConcreteType);
+ Logger newLogger;
+
+ if (cacheKey.ConcreteType != null && cacheKey.ConcreteType != typeof(Logger))
+ newLogger = (Logger)FactoryHelper.CreateInstance(cacheKey.ConcreteType);
+ else
+ newLogger = new Logger();
+
+ if (cacheKey.ConcreteType != null)
+
+ newLogger.Initialize(cacheKey.Name, GetConfigurationForLogger(cacheKey.Name, Configuration), this);
+ _loggerCache[cacheKey] = newLogger;
+ return newLogger;
+ }
+ }
+
+ /// <summary>
+ /// Gets the specified named logger.
+ /// </summary>
+ /// <param name="name">name of the logger</param>
+ /// <returns>The logger reference. Multiple calls to <c>GetLogger</c> with the same argument aren't guaranteed to return the same logger reference.</returns>
+ public Logger GetLogger(string name)
+ {
+ return GetLogger(new LoggerCacheKey(typeof(Logger),name));
+ }
+
+ /// <summary>
+ /// Gets the specified named logger.
+ /// </summary>
+ /// <param name="name">name of the logger</param>
+ /// <param name="loggerType">type of the logger to create. The type must inherit from NLog.Logger</param>
+ /// <returns>The logger reference. Multiple calls to <c>GetLogger</c> with the
+ /// same argument aren't guaranteed to return the same logger reference.</returns>
+ public Logger GetLogger(string name, Type loggerType)
+ {
+ return GetLogger(new LoggerCacheKey(loggerType,name));
+ }
+
+ /// <summary>
+ /// Gets or sets the current logging configuration.
+ /// </summary>
+ public LoggingConfiguration Configuration
+ {
+ get
+ {
+ lock(this)
+ {
+ if (_configLoaded)
+ return _config;
+
+ _configLoaded = true;
+#if !NETCF
+ if (_config == null)
+ {
+ // try to load default configuration
+ _config = XmlLoggingConfiguration.AppConfig;
+ }
+ if (_config == null)
+ {
+ string configFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NLog.config");
+ if (File.Exists(configFile))
+ {
+ InternalLogger.Debug("Attempting to load config from {0}", configFile);
+ _config = new XmlLoggingConfiguration(configFile);
+ }
+ }
+ if (_config == null)
+ {
+ string configFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
+ if (configFile != null)
+ {
+ configFile = Path.ChangeExtension(configFile, ".nlog");
+ if (File.Exists(configFile))
+ {
+ InternalLogger.Debug("Attempting to load config from {0}", configFile);
+ _config = new XmlLoggingConfiguration(configFile);
+ }
+ }
+ }
+ if (_config == null)
+ {
+ Assembly nlogAssembly = typeof(LoggingConfiguration).Assembly;
+ if (!nlogAssembly.GlobalAssemblyCache)
+ {
+ string configFile = nlogAssembly.Location + ".nlog";
+ if (File.Exists(configFile))
+ {
+ InternalLogger.Debug("Attempting to load config from {0}", configFile);
+ _config = new XmlLoggingConfiguration(configFile);
+ }
+ }
+ }
+
+ if (_config == null)
+ {
+ if (EnvironmentHelper.GetSafeEnvironmentVariable("NLOG_GLOBAL_CONFIG_FILE") != null)
+ {
+ string configFile = Environment.GetEnvironmentVariable("NLOG_GLOBAL_CONFIG_FILE");
+ if (File.Exists(configFile))
+ {
+ InternalLogger.Debug("Attempting to load config from {0}", configFile);
+ _config = new XmlLoggingConfiguration(configFile);
+ }
+ else
+ {
+ InternalLogger.Warn("NLog global config file pointed by NLOG_GLOBAL_CONFIG '{0}' doesn't exist.", configFile);
+ }
+ }
+ }
+
+ if (_config != null)
+ {
+ Dump(_config);
+ _watcher.Watch(_config.FileNamesToWatch);
+ }
+#else
+ if (_config == null)
+ {
+ string configFile = CompactFrameworkHelper.GetExeFileName() + ".nlog";
+ if (File.Exists(configFile))
+ {
+ InternalLogger.Debug("Attempting to load config from {0}", configFile);
+ _config = new XmlLoggingConfiguration(configFile);
+ }
+ }
+ if (_config == null)
+ {
+ string configFile = Path.Combine(Path.GetDirectoryName(CompactFrameworkHelper.GetExeFileName()), "NLog.config");
+ if (File.Exists(configFile))
+ {
+ InternalLogger.Debug("Attempting to load config from {0}", configFile);
+ _config = new XmlLoggingConfiguration(configFile);
+ }
+ }
+ if (_config == null)
+ {
+ string configFile = typeof(LogFactory).Assembly.GetName().CodeBase + ".nlog";
+ if (File.Exists(configFile))
+ {
+ InternalLogger.Debug("Attempting to load config from {0}", configFile);
+ _config = new XmlLoggingConfiguration(configFile);
+ }
+ }
+#endif
+ if (_config != null)
+ {
+ _config.InitializeAll();
+ }
+ return _config;
+ }
+ }
+
+ set
+ {
+#if !NETCF
+ try
+ {
+ _watcher.StopWatching();
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Cannot stop file watching: {0}", ex);
+ }
+#endif
+
+ lock(this)
+ {
+ LoggingConfiguration oldConfig = _config;
+ if (oldConfig != null)
+ {
+ InternalLogger.Info("Closing old configuration.");
+ oldConfig.Close();
+ }
+
+ _config = value;
+ _configLoaded = true;
+
+ if (_config != null)
+ {
+ Dump(_config);
+
+ _config.InitializeAll();
+ ReconfigExistingLoggers(_config);
+#if !NETCF
+ try
+ {
+ _watcher.Watch(_config.FileNamesToWatch);
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Warn("Cannot start file watching: {0}", ex);
+ }
+#endif
+ }
+ if (ConfigurationChanged != null)
+ ConfigurationChanged(oldConfig, value);
+ }
+ }
+ }
+
+#if !NETCF
+ private MultiFileWatcher _watcher;
+ private Timer _reloadTimer = null;
+
+ const int ReconfigAfterFileChangedTimeout = 1000;
+
+ private void ConfigFileChanged(object sender, EventArgs args)
+ {
+ InternalLogger.Info("Configuration file change detected! Reloading in {0}ms...", ReconfigAfterFileChangedTimeout);
+
+ // In the rare cases we may get multiple notifications here,
+ // but we need to reload config only once.
+ //
+ // The trick is to schedule the reload in one second after
+ // the last change notification comes in.
+
+ lock (this)
+ {
+ if (_reloadTimer == null)
+ {
+ _reloadTimer = new Timer(new TimerCallback(ReloadConfigOnTimer), Configuration, ReconfigAfterFileChangedTimeout, Timeout.Infinite);
+ }
+ else
+ {
+ _reloadTimer.Change(ReconfigAfterFileChangedTimeout, Timeout.Infinite);
+ }
+ }
+ }
+#endif
+
+ private void Dump(LoggingConfiguration config)
+ {
+ if (!InternalLogger.IsDebugEnabled)
+ return;
+
+ InternalLogger.Debug("--- NLog configuration dump. ---");
+ InternalLogger.Debug("Targets:");
+ foreach (Target target in config._targets.Values)
+ {
+ InternalLogger.Info("{0}", target);
+ }
+ InternalLogger.Debug("Rules:");
+ foreach (LoggingRule rule in config.LoggingRules)
+ {
+ InternalLogger.Info("{0}", rule);
+ }
+ InternalLogger.Debug("--- End of NLog configuration dump ---");
+ }
+
+#if !NETCF
+ internal void ReloadConfigOnTimer(object state)
+ {
+ LoggingConfiguration configurationToReload = (LoggingConfiguration)state;
+
+ InternalLogger.Info("Reloading configuration...");
+ lock(this)
+ {
+ if (_reloadTimer != null)
+ {
+ _reloadTimer.Dispose();
+ _reloadTimer = null;
+ }
+
+ _watcher.StopWatching();
+ try
+ {
+ if (Configuration != configurationToReload)
+ {
+ throw new Exception("Config changed in between. Not reloading.");
+ }
+
+ LoggingConfiguration newConfig = configurationToReload.Reload();
+ if (newConfig != null)
+ {
+ Configuration = newConfig;
+ if (ConfigurationReloaded != null)
+ ConfigurationReloaded(true, null);
+ }
+ else
+ {
+ throw new Exception("Configuration.Reload() returned null. Not reloading.");
+ }
+ }
+ catch (Exception ex)
+ {
+ _watcher.Watch(configurationToReload.FileNamesToWatch);
+ if (ConfigurationReloaded != null)
+ ConfigurationReloaded(false, ex);
+ }
+ }
+ }
+#endif
+
+ /// <summary>
+ /// Loops through all loggers previously returned by GetLogger
+ /// and recalculates their target and filter list. Useful after modifying the configuration programmatically
+ /// to ensure that all loggers have been properly configured.
+ /// </summary>
+ public void ReconfigExistingLoggers()
+ {
+ ReconfigExistingLoggers(Configuration);
+ }
+
+ internal void ReconfigExistingLoggers(LoggingConfiguration config)
+ {
+ foreach (Logger logger in _loggerCache.Values)
+ {
+ logger.SetConfiguration(GetConfigurationForLogger(logger.Name, config));
+ }
+ }
+
+ internal void GetTargetsByLevelForLogger(string name, LoggingRuleCollection rules, TargetWithFilterChain[]targetsByLevel, TargetWithFilterChain[]lastTargetsByLevel)
+ {
+ foreach (LoggingRule rule in rules)
+ {
+ if (rule.NameMatches(name))
+ {
+ for (int i = 0; i <= LogLevel.MaxLevel.Ordinal; ++i)
+ {
+ if (i >= GlobalThreshold.Ordinal && rule.IsLoggingEnabledForLevel(LogLevel.FromOrdinal(i)))
+ {
+ foreach (Target target in rule.Targets)
+ {
+ TargetWithFilterChain awf = new TargetWithFilterChain(target, rule.Filters);
+ if (lastTargetsByLevel[i] != null)
+ {
+ lastTargetsByLevel[i].Next = awf;
+ }
+ else
+ {
+ targetsByLevel[i] = awf;
+ }
+ lastTargetsByLevel[i] = awf;
+ }
+ }
+ }
+
+ GetTargetsByLevelForLogger(name, rule.ChildRules, targetsByLevel, lastTargetsByLevel);
+
+ if (rule.Final)
+ break;
+ }
+ }
+ for (int i = 0; i <= LogLevel.MaxLevel.Ordinal; ++i)
+ {
+ TargetWithFilterChain tfc = targetsByLevel[i];
+ if (tfc != null)
+ tfc.PrecalculateNeedsStackTrace();
+ }
+ }
+
+ internal LoggerConfiguration GetConfigurationForLogger(string name, LoggingConfiguration config)
+ {
+ TargetWithFilterChain[]targetsByLevel = new TargetWithFilterChain[LogLevel.MaxLevel.Ordinal + 1];
+ TargetWithFilterChain[]lastTargetsByLevel = new TargetWithFilterChain[LogLevel.MaxLevel.Ordinal + 1];
+
+ if (config != null && IsLoggingEnabled())
+ {
+ GetTargetsByLevelForLogger(name, config.LoggingRules, targetsByLevel, lastTargetsByLevel);
+ }
+
+ InternalLogger.Debug("Targets for {0} by level:", name);
+ for (int i = 0; i <= LogLevel.MaxLevel.Ordinal; ++i)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat(CultureInfo.InvariantCulture, "{0} =>", LogLevel.FromOrdinal(i));
+ for (TargetWithFilterChain afc = targetsByLevel[i]; afc != null; afc = afc.Next)
+ {
+ sb.AppendFormat(CultureInfo.InvariantCulture, " {0}", afc.Target.Name);
+ if (afc.FilterChain.Count > 0)
+ sb.AppendFormat(CultureInfo.InvariantCulture, " ({0} filters)", afc.FilterChain.Count);
+ }
+ InternalLogger.Debug(sb.ToString());
+ }
+
+ return new LoggerConfiguration(targetsByLevel);
+ }
+
+ /// <summary>
+ /// Flush any pending log messages (in case of asynchronous targets).
+ /// </summary>
+ public void Flush()
+ {
+ Configuration.FlushAllTargets(TimeSpan.MaxValue);
+ }
+
+ /// <summary>
+ /// Flush any pending log messages (in case of asynchronous targets).
+ /// </summary>
+ /// <param name="timeout">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
+ public void Flush(TimeSpan timeout)
+ {
+ Configuration.FlushAllTargets(timeout);
+ }
+
+ /// <summary>
+ /// Flush any pending log messages (in case of asynchronous targets).
+ /// </summary>
+ /// <param name="timeoutMilliseconds">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
+ public void Flush(int timeoutMilliseconds)
+ {
+ Configuration.FlushAllTargets(TimeSpan.FromMilliseconds(timeoutMilliseconds));
+ }
+
+ class LogEnabler: IDisposable
+ {
+ private LogFactory _factory;
+
+ public LogEnabler(LogFactory factory)
+ {
+ _factory = factory;
+ }
+
+ void IDisposable.Dispose()
+ {
+ _factory.EnableLogging();
+ }
+ }
+
+ /// <summary>Decreases the log enable counter and if it reaches -1
+ /// the logs are disabled.</summary>
+ /// <remarks>Logging is enabled if the number of <see cref="EnableLogging"/> calls is greater
+ /// than or equal to <see cref="DisableLogging"/> calls.</remarks>
+ /// <returns>An object that iplements IDisposable whose Dispose() method
+ /// reenables logging. To be used with C# <c>using ()</c> statement.</returns>
+ public IDisposable DisableLogging()
+ {
+ lock (this)
+ {
+ _logsEnabled--;
+ if (_logsEnabled == -1)
+ ReconfigExistingLoggers();
+ }
+ return new LogEnabler(this);
+ }
+
+ /// <summary>Increases the log enable counter and if it reaches 0 the logs are disabled.</summary>
+ /// <remarks>Logging is enabled if the number of <see cref="EnableLogging"/> calls is greater
+ /// than or equal to <see cref="DisableLogging"/> calls.</remarks>
+ public void EnableLogging()
+ {
+ lock (this)
+ {
+ _logsEnabled++;
+ if (_logsEnabled == 0)
+ ReconfigExistingLoggers();
+ }
+ }
+
+ /// <summary>
+ /// Returns <see langword="true" /> if logging is currently enabled.
+ /// </summary>
+ /// <returns><see langword="true" /> if logging is currently enabled,
+ /// <see langword="false"/> otherwise.</returns>
+ /// <remarks>Logging is enabled if the number of <see cref="EnableLogging"/> calls is greater
+ /// than or equal to <see cref="DisableLogging"/> calls.</remarks>
+ public bool IsLoggingEnabled()
+ {
+ return _logsEnabled >= 0;
+ }
+
+ /// <summary>
+ /// Global log threshold. Log events below this threshold are not logged.
+ /// </summary>
+ public LogLevel GlobalThreshold
+ {
+ get { return _globalThreshold; }
+ set
+ {
+ lock(this)
+ {
+ _globalThreshold = value;
+ ReconfigExistingLoggers();
+ }
+ }
+ }
+ }
+
+#if NET_2_API
+ /// <summary>
+ /// Specialized LogFactory that can return instances of custom logger types.
+ /// </summary>
+ /// <typeparam name="LoggerType">The type of the logger to be returned. Must inherit from <see cref="Logger"/>.</typeparam>
+ public class LogFactory<LoggerType> : LogFactory where LoggerType : Logger
+ {
+ /// <summary>
+ /// Gets the logger.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <returns>An instance of <typeparamref name="LoggerType"/>.</returns>
+ public new LoggerType GetLogger(string name)
+ {
+ return (LoggerType)base.GetLogger(name, typeof(LoggerType));
+ }
+
+#if !NETCF
+ /// <summary>
+ /// Gets the logger named after the currently-being-initialized class.
+ /// </summary>
+ /// <returns>The logger.</returns>
+ /// <remarks>This is a slow-running method.
+ /// Make sure you're not doing this in a loop.</remarks>
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public new LoggerType GetCurrentClassLogger()
+ {
+ StackFrame frame = new StackFrame(1, false);
+
+ return GetLogger(frame.GetMethod().DeclaringType.FullName);
+ }
+#endif
+
+ }
+#endif
+}
diff --git a/src/NLog/LogLevel.cs b/src/NLog/LogLevel.cs
new file mode 100644
index 0000000..da96797
--- /dev/null
+++ b/src/NLog/LogLevel.cs
@@ -0,0 +1,251 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog
+{
+ /// <summary>
+ /// Defines available log levels.
+ /// </summary>
+ public class LogLevel : IComparable
+ {
+ private string _name;
+ private string _uppercaseName;
+ private string _lowercaseName;
+ private int _ordinal;
+
+ /// <summary>
+ /// The Trace level.
+ /// </summary>
+ public static readonly LogLevel Trace;
+
+ /// <summary>
+ /// The Debug level.
+ /// </summary>
+ public static readonly LogLevel Debug;
+
+ /// <summary>
+ /// The Info level.
+ /// </summary>
+ public static readonly LogLevel Info;
+
+ /// <summary>
+ /// The Warn level.
+ /// </summary>
+ public static readonly LogLevel Warn;
+
+ /// <summary>
+ /// The Error level.
+ /// </summary>
+ public static readonly LogLevel Error;
+
+ /// <summary>
+ /// The Fatal level.
+ /// </summary>
+ public static readonly LogLevel Fatal;
+
+ /// <summary>
+ /// The Off level.
+ /// </summary>
+ public static readonly LogLevel Off;
+
+ internal static readonly LogLevel MaxLevel;
+ internal static readonly LogLevel MinLevel;
+
+ private static LogLevel[] _levelByOrdinal;
+
+ static LogLevel()
+ {
+ int l = 0;
+
+ Trace = new LogLevel("Trace", l++);
+ Debug = new LogLevel("Debug", l++);
+ Info = new LogLevel("Info", l++);
+ Warn = new LogLevel("Warn", l++);
+ Error = new LogLevel("Error", l++);
+ Fatal = new LogLevel("Fatal", l++);
+ Off = new LogLevel("Off", l++);
+
+ _levelByOrdinal = new LogLevel[] { Trace, Debug, Info, Warn, Error, Fatal, Off };
+ MinLevel = _levelByOrdinal[0];
+ MaxLevel = _levelByOrdinal[_levelByOrdinal.Length - 2]; // ignore the Off level
+ }
+
+ // to be changed into public in the future.
+ private LogLevel(string name, int ordinal)
+ {
+ _name = name;
+ _uppercaseName = name.ToUpper();
+ _lowercaseName = name.ToLower();
+ _ordinal = ordinal;
+ }
+
+ /// <summary>
+ /// Gets the name of the log level.
+ /// </summary>
+ public string Name
+ {
+ get { return _name; }
+ }
+
+ /// <summary>
+ /// Gets the name of the logger in upper case.
+ /// </summary>
+ public string UppercaseName
+ {
+ get { return _uppercaseName; }
+ }
+
+ /// <summary>
+ /// Gets the name of the logger in lower case.
+ /// </summary>
+ public string LowercaseName
+ {
+ get { return _lowercaseName; }
+ }
+
+ internal int Ordinal
+ {
+ get { return _ordinal; }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="LogLevel"/> that corresponds to the specified ordinal.
+ /// </summary>
+ /// <param name="ordinal">The ordinal.</param>
+ /// <returns>The <see cref="LogLevel"/> instance. For 0 it returns <see cref="LogLevel.Debug"/>, 1 gives <see cref="LogLevel.Info"/> and so on</returns>
+ public static LogLevel FromOrdinal(int ordinal)
+ {
+ return _levelByOrdinal[ordinal];
+ }
+
+ /// <summary>
+ /// Compares two <see cref="LogLevel"/> objects
+ /// and returns a value indicating whether
+ /// the first one is less than or equal to the second one.
+ /// </summary>
+ /// <param name="l1">The first level.</param>
+ /// <param name="l2">The second level.</param>
+ /// <returns>The value of <c>l1.Ordinal <= l2.Ordinal</c></returns>
+ public static bool operator <=(LogLevel l1, LogLevel l2)
+ {
+ return l1.Ordinal <= l2.Ordinal;
+ }
+
+ /// <summary>
+ /// Compares two <see cref="LogLevel"/> objects
+ /// and returns a value indicating whether
+ /// the first one is greater than or equal to the second one.
+ /// </summary>
+ /// <param name="l1">The first level.</param>
+ /// <param name="l2">The second level.</param>
+ /// <returns>The value of <c>l1.Ordinal >= l2.Ordinal</c></returns>
+ public static bool operator >=(LogLevel l1, LogLevel l2)
+ {
+ return l1.Ordinal >= l2.Ordinal;
+ }
+
+ /// <summary>
+ /// Compares two <see cref="LogLevel"/> objects
+ /// and returns a value indicating whether
+ /// the first one is less than the second one.
+ /// </summary>
+ /// <param name="l1">The first level.</param>
+ /// <param name="l2">The second level.</param>
+ /// <returns>The value of <c>l1.Ordinal < l2.Ordinal</c></returns>
+ public static bool operator <(LogLevel l1, LogLevel l2)
+ {
+ return l1.Ordinal < l2.Ordinal;
+ }
+
+ /// <summary>
+ /// Compares two <see cref="LogLevel"/> objects
+ /// and returns a value indicating whether
+ /// the first one is greater than the second one.
+ /// </summary>
+ /// <param name="l1">The first level.</param>
+ /// <param name="l2">The second level.</param>
+ /// <returns>The value of <c>l1.Ordinal > l2.Ordinal</c></returns>
+ public static bool operator >(LogLevel l1, LogLevel l2)
+ {
+ return l1.Ordinal > l2.Ordinal;
+ }
+
+ /// <summary>
+ /// Returns the <see cref="T:NLog.LogLevel"/> that corresponds to the supplied <see langword="string" />.
+ /// </summary>
+ /// <param name="s">the texual representation of the log level</param>
+ /// <returns>the enumeration value.</returns>
+ public static LogLevel FromString(string s)
+ {
+ // case sensitive search first
+ for (int i = 0; i < _levelByOrdinal.Length; ++i)
+ {
+ if (_levelByOrdinal[i].Name == s)
+ return _levelByOrdinal[i];
+ }
+
+ // case insensitive search
+ for (int i = 0; i < _levelByOrdinal.Length; ++i)
+ {
+ if (0 == String.Compare(_levelByOrdinal[i].Name, s, true))
+ return _levelByOrdinal[i];
+ }
+ throw new ArgumentException("Unknown log level: " + s);
+ }
+
+ /// <summary>
+ /// Returns a string representation of the log level.
+ /// </summary>
+ /// <returns>Log level name.</returns>
+ public override string ToString()
+ {
+ return Name;
+ }
+
+ /// <summary>
+ /// Compares the level to the other <see cref="LogLevel"/> object.
+ /// </summary>
+ /// <param name="obj">the object object</param>
+ /// <returns>a value less than zero when this logger's <see cref="Ordinal"/> is
+ /// less than the other logger's ordinal, 0 when they are equal and
+ /// greater than zero when this ordinal is greater than the
+ /// other ordinal.</returns>
+ public int CompareTo(object obj)
+ {
+ LogLevel l = (LogLevel)obj;
+ return this.Ordinal - l.Ordinal;
+ }
+ }
+}
diff --git a/src/NLog/LogManager.cs b/src/NLog/LogManager.cs
new file mode 100644
index 0000000..14ad295
--- /dev/null
+++ b/src/NLog/LogManager.cs
@@ -0,0 +1,269 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using System.Diagnostics;
+using System.Security;
+using System.Text;
+using System.Runtime.CompilerServices;
+using System.Globalization;
+
+using NLog.Config;
+using NLog.Internal;
+using NLog.Targets;
+
+namespace NLog
+{
+ /// <summary>
+ /// Creates and manages instances of <see cref="T:NLog.Logger" /> objects.
+ /// </summary>
+ public sealed class LogManager
+ {
+ private static LogFactory _globalFactory = new LogFactory();
+
+ /// <summary>
+ /// Occurs when logging <see cref="Configuration" /> changes.
+ /// </summary>
+ public static event LoggingConfigurationChanged ConfigurationChanged
+ {
+ add { _globalFactory.ConfigurationChanged += value; }
+ remove { _globalFactory.ConfigurationChanged -= value; }
+ }
+
+#if !NETCF
+ /// <summary>
+ /// Occurs when logging <see cref="Configuration" /> gets reloaded.
+ /// </summary>
+ public static event LoggingConfigurationReloaded ConfigurationReloaded
+ {
+ add { _globalFactory.ConfigurationReloaded += value; }
+ remove { _globalFactory.ConfigurationReloaded -= value; }
+ }
+#endif
+ /// <summary>
+ /// Specified whether NLog should throw exceptions. By default exceptions
+ /// are not thrown under any circumstances.
+ /// </summary>
+ public static bool ThrowExceptions
+ {
+ get { return _globalFactory.ThrowExceptions; }
+ set { _globalFactory.ThrowExceptions = value; }
+ }
+
+ private LogManager(){}
+
+#if !NETCF
+ /// <summary>
+ /// Gets the logger named after the currently-being-initialized class.
+ /// </summary>
+ /// <returns>The logger.</returns>
+ /// <remarks>This is a slow-running method.
+ /// Make sure you're not doing this in a loop.</remarks>
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static Logger GetCurrentClassLogger()
+ {
+ StackFrame frame = new StackFrame(1, false);
+
+ return _globalFactory.GetLogger(frame.GetMethod().DeclaringType.FullName);
+ }
+
+ /// <summary>
+ /// Gets the logger named after the currently-being-initialized class.
+ /// </summary>
+ /// <param name="loggerType">the logger class. The class must inherit from <see cref="Logger" /></param>
+ /// <returns>The logger.</returns>
+ /// <remarks>This is a slow-running method.
+ /// Make sure you're not doing this in a loop.</remarks>
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static Logger GetCurrentClassLogger(Type loggerType)
+ {
+ StackFrame frame = new StackFrame(1, false);
+
+ return _globalFactory.GetLogger(frame.GetMethod().DeclaringType.FullName, loggerType);
+ }
+#endif
+
+ /// <summary>
+ /// Creates a logger that discards all log messages.
+ /// </summary>
+ /// <returns></returns>
+ public static Logger CreateNullLogger()
+ {
+ return _globalFactory.CreateNullLogger();
+
+ }
+
+ /// <summary>
+ /// Gets the specified named logger.
+ /// </summary>
+ /// <param name="name">name of the logger</param>
+ /// <returns>The logger reference. Multiple calls to <c>GetLogger</c> with the same argument aren't guaranteed to return the same logger reference.</returns>
+ public static Logger GetLogger(string name)
+ {
+ return _globalFactory.GetLogger(name);
+ }
+
+ /// <summary>
+ /// Gets the specified named logger.
+ /// </summary>
+ /// <param name="name">name of the logger</param>
+ /// <param name="loggerType">the logger class. The class must inherit from <see cref="Logger" /></param>
+ /// <returns>The logger reference. Multiple calls to <c>GetLogger</c> with the same argument aren't guaranteed to return the same logger reference.</returns>
+ public static Logger GetLogger(string name, Type loggerType)
+ {
+ return _globalFactory.GetLogger(name, loggerType);
+ }
+
+ /// <summary>
+ /// Gets or sets the current logging configuration.
+ /// </summary>
+ public static LoggingConfiguration Configuration
+ {
+ get { return _globalFactory.Configuration; }
+ set { _globalFactory.Configuration = value; }
+ }
+
+
+ /// <summary>
+ /// Loops through all loggers previously returned by GetLogger.
+ /// and recalculates their target and filter list. Useful after modifying the configuration programmatically
+ /// to ensure that all loggers have been properly configured.
+ /// </summary>
+ public static void ReconfigExistingLoggers()
+ {
+ _globalFactory.ReconfigExistingLoggers();
+ }
+
+ /// <summary>
+ /// Flush any pending log messages (in case of asynchronous targets).
+ /// </summary>
+ public static void Flush()
+ {
+ _globalFactory.Flush();
+ }
+
+ /// <summary>
+ /// Flush any pending log messages (in case of asynchronous targets).
+ /// </summary>
+ /// <param name="timeout">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
+ public static void Flush(TimeSpan timeout)
+ {
+ _globalFactory.Flush(timeout);
+ }
+
+ /// <summary>
+ /// Flush any pending log messages (in case of asynchronous targets).
+ /// </summary>
+ /// <param name="timeoutMilliseconds">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
+ public static void Flush(int timeoutMilliseconds)
+ {
+ _globalFactory.Flush(timeoutMilliseconds);
+ }
+
+ /// <summary>Decreases the log enable counter and if it reaches -1
+ /// the logs are disabled.</summary>
+ /// <remarks>Logging is enabled if the number of <see cref="EnableLogging"/> calls is greater
+ /// than or equal to <see cref="DisableLogging"/> calls.</remarks>
+ /// <returns>An object that iplements IDisposable whose Dispose() method
+ /// reenables logging. To be used with C# <c>using ()</c> statement.</returns>
+ public static IDisposable DisableLogging()
+ {
+ return _globalFactory.DisableLogging();
+ }
+
+ /// <summary>Increases the log enable counter and if it reaches 0 the logs are disabled.</summary>
+ /// <remarks>Logging is enabled if the number of <see cref="EnableLogging"/> calls is greater
+ /// than or equal to <see cref="DisableLogging"/> calls.</remarks>
+ public static void EnableLogging()
+ {
+ _globalFactory.EnableLogging();
+ }
+
+ /// <summary>
+ /// Returns <see langword="true" /> if logging is currently enabled.
+ /// </summary>
+ /// <returns><see langword="true" /> if logging is currently enabled,
+ /// <see langword="false"/> otherwise.</returns>
+ /// <remarks>Logging is enabled if the number of <see cref="EnableLogging"/> calls is greater
+ /// than or equal to <see cref="DisableLogging"/> calls.</remarks>
+ public static bool IsLoggingEnabled()
+ {
+ return _globalFactory.IsLoggingEnabled();
+ }
+
+ /// <summary>
+ /// Global log threshold. Log events below this threshold are not logged.
+ /// </summary>
+ public static LogLevel GlobalThreshold
+ {
+ get { return _globalFactory.GlobalThreshold; }
+ set { _globalFactory.GlobalThreshold = value; }
+ }
+
+#if !NETCF
+ private static void SetupTerminationEvents()
+ {
+ AppDomain.CurrentDomain.ProcessExit += new EventHandler(TurnOffLogging);
+ AppDomain.CurrentDomain.DomainUnload += new EventHandler(TurnOffLogging);
+ }
+
+ private static void TurnOffLogging(object sender, EventArgs args)
+ {
+ // reset logging configuration to null
+ // this causes old configuration (if any) to be closed.
+
+ InternalLogger.Info("Shutting down logging...");
+ Configuration = null;
+ InternalLogger.Info("Logger has been shut down.");
+ }
+#endif
+ static LogManager()
+ {
+#if !NETCF
+ try
+ {
+ SetupTerminationEvents();
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Warn("Error setting up termiation events: {0}", ex);
+ }
+#endif
+ }
+ }
+}
diff --git a/src/NLog/Logger.cs b/src/NLog/Logger.cs
new file mode 100644
index 0000000..3358864
--- /dev/null
+++ b/src/NLog/Logger.cs
@@ -0,0 +1,2697 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+using NLog.Internal;
+
+namespace NLog
+{
+ /// <summary>
+ /// Represents a method that's invoked each time a <see cref="Logger"/> configuration changes.
+ /// </summary>
+ /// <param name="logger">logger that was reconfigured</param>
+ /// <remarks>
+ /// 'Reconfiguring' a logger means rebuilding the list of targets and filters
+ /// that will be invoked on logging.
+ /// This may or may not influence the result returned by IsXXXXEnabled properties.
+ /// </remarks>
+ public delegate void LoggerReconfiguredDelegate(Logger logger);
+
+ /// <summary>
+ /// Provides logging interface and utility functions.
+ /// </summary>
+ [CLSCompliant(true)]
+ public class Logger
+ {
+ private string _loggerName;
+ private LogFactory _factory;
+ private Type _loggerType = typeof(Logger);
+#if !NETCF_1_0
+ private volatile LoggerConfiguration _configuration;
+ private volatile bool _isTraceEnabled;
+ private volatile bool _isDebugEnabled;
+ private volatile bool _isInfoEnabled;
+ private volatile bool _isWarnEnabled;
+ private volatile bool _isErrorEnabled;
+ private volatile bool _isFatalEnabled;
+#else
+ private LoggerConfiguration _configuration;
+ private bool _isTraceEnabled;
+ private bool _isDebugEnabled;
+ private bool _isInfoEnabled;
+ private bool _isWarnEnabled;
+ private bool _isErrorEnabled;
+ private bool _isFatalEnabled;
+#endif
+ /// <summary>
+ /// Occurs when logger configuration changes.
+ /// </summary>
+ /// <remarks>
+ /// </remarks>
+ public event LoggerReconfiguredDelegate LoggerReconfigured;
+
+ private TargetWithFilterChain GetTargetsForLevel(LogLevel level)
+ {
+ return _configuration.GetTargetsForLevel(level);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Logger"/> class.
+ /// </summary>
+ protected internal Logger()
+ {
+ }
+
+ internal void Initialize(string name, LoggerConfiguration configuration, LogFactory factory)
+ {
+ _loggerName = name;
+ _factory = factory;
+ SetConfiguration(configuration);
+ }
+
+ /// <summary>
+ /// Gets the name of the logger.
+ /// </summary>
+ public string Name
+ {
+ get { return _loggerName; }
+ }
+
+ /// <summary>
+ /// Gets the factory that created this logger.
+ /// </summary>
+ public LogFactory Factory
+ {
+ get { return _factory; }
+ }
+
+ internal void WriteToTargets(LogLevel level, IFormatProvider formatProvider, string message, object[]args, Exception exception)
+ {
+ LogEventInfo logMessage = new LogEventInfo(level, this.Name, formatProvider, message, args, exception);
+ LoggerImpl.Write(_loggerType, GetTargetsForLevel(level), logMessage, _factory);
+ }
+
+ internal void WriteToTargets(LogLevel level, string message)
+ {
+ LogEventInfo logMessage = new LogEventInfo(level, this.Name, null, message, null, null);
+ LoggerImpl.Write(_loggerType, GetTargetsForLevel(level), logMessage, _factory);
+ }
+
+ internal void WriteToTargets(LogLevel level, string message, object[]args)
+ {
+ LogEventInfo logMessage = new LogEventInfo(level, this.Name, null, message, args, null);
+ LoggerImpl.Write(_loggerType, GetTargetsForLevel(level), logMessage, _factory);
+ }
+
+ internal void WriteToTargets(LogEventInfo logEvent)
+ {
+ LoggerImpl.Write(_loggerType, GetTargetsForLevel(logEvent.Level), logEvent, _factory);
+ }
+
+ internal void WriteToTargets(Type wrapperType, LogEventInfo logEvent)
+ {
+ LoggerImpl.Write(wrapperType, GetTargetsForLevel(logEvent.Level), logEvent, _factory);
+ }
+
+ internal void SetConfiguration(LoggerConfiguration configuration)
+ {
+ _configuration = configuration;
+
+ // pre-calculate 'enabled' flags
+ _isTraceEnabled = configuration.IsEnabled(LogLevel.Trace);
+ _isDebugEnabled = configuration.IsEnabled(LogLevel.Debug);
+ _isInfoEnabled = configuration.IsEnabled(LogLevel.Info);
+ _isWarnEnabled = configuration.IsEnabled(LogLevel.Warn);
+ _isErrorEnabled = configuration.IsEnabled(LogLevel.Error);
+ _isFatalEnabled = configuration.IsEnabled(LogLevel.Fatal);
+
+ if (LoggerReconfigured != null)
+ LoggerReconfigured(this);
+ }
+
+ /// <summary>
+ /// Determines if logging is enabled for the specified level.
+ /// </summary>
+ /// <param name="level">level to be checked</param>
+ /// <returns><see langword="true" /> if logging is enabled for the specified level, otherwise it returns <see langword="false" />.</returns>
+ public bool IsEnabled(LogLevel level)
+ {
+ return GetTargetsForLevel(level) != null;
+ }
+
+ /// <summary>
+ /// Determines if logging is enabled for the <c>Trace</c> level.
+ /// </summary>
+ /// <returns><see langword="true" /> if logging is enabled for the <c>Trace</c> level, otherwise it returns <see langword="false" />.</returns>
+ public bool IsTraceEnabled
+ {
+ get { return _isTraceEnabled; }
+ }
+
+ /// <summary>
+ /// Determines if logging is enabled for the <c>Debug</c> level.
+ /// </summary>
+ /// <returns><see langword="true" /> if logging is enabled for the <c>Debug</c> level, otherwise it returns <see langword="false" />.</returns>
+ public bool IsDebugEnabled
+ {
+ get
+ {
+ return _isDebugEnabled;
+ }
+ }
+
+ /// <summary>
+ /// Determines if logging is enabled for the <c>Info</c> level.
+ /// </summary>
+ /// <returns><see langword="true" /> if logging is enabled for the <c>Info</c> level, otherwise it returns <see langword="false" />.</returns>
+ public bool IsInfoEnabled
+ {
+ get
+ {
+ return _isInfoEnabled;
+ }
+ }
+
+ /// <summary>
+ /// Determines if logging is enabled for the <c>Warn</c> level.
+ /// </summary>
+ /// <returns><see langword="true" /> if logging is enabled for the <c>Warn</c> level, otherwise it returns <see langword="false" />.</returns>
+ public bool IsWarnEnabled
+ {
+ get { return _isWarnEnabled; }
+ }
+
+ /// <summary>
+ /// Determines if logging is enabled for the <c>Error</c> level.
+ /// </summary>
+ /// <returns><see langword="true" /> if logging is enabled for the <c>Error</c> level, otherwise it returns <see langword="false" />.</returns>
+ public bool IsErrorEnabled
+ {
+ get
+ {
+ return _isErrorEnabled;
+ }
+ }
+
+ /// <summary>
+ /// Determines if logging is enabled for the <c>Fatal</c> level.
+ /// </summary>
+ /// <returns><see langword="true" /> if logging is enabled for the <c>Fatal</c> level, otherwise it returns <see langword="false" />.</returns>
+ public bool IsFatalEnabled
+ {
+ get
+ {
+ return _isFatalEnabled;
+ }
+ }
+
+ /// <overloads>
+ /// Writes the diagnostic message at the specified level using the specified format provider and format parameters.
+ /// </overloads>
+ /// <summary>
+ /// Writes the specified diagnostic message.
+ /// </summary>
+ /// <param name="logEvent">log event</param>
+ public void Log(LogEventInfo logEvent)
+ {
+ if (IsEnabled(logEvent.Level))
+ WriteToTargets(logEvent);
+ }
+
+ /// <overloads>
+ /// Writes the diagnostic message at the specified level using the specified format provider and format parameters.
+ /// </overloads>
+ /// <summary>
+ /// Writes the specified diagnostic message.
+ /// </summary>
+ /// <param name="logEvent">log event</param>
+ /// <param name="wrapperType">The name of the type that wraps Logger</param>
+ public void Log(Type wrapperType, LogEventInfo logEvent)
+ {
+ if (IsEnabled(logEvent.Level))
+ WriteToTargets(wrapperType, logEvent);
+ }
+
+ // the following code has been automatically generated by a PERL script
+
+ #region Log() overloads
+
+ /// <overloads>
+ /// Writes the diagnostic message at the specified level using the specified format provider and format parameters.
+ /// </overloads>
+ /// <summary>
+ /// Writes the diagnostic message at the specified level.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ public void Log(LogLevel level, string message) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the specified level.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Log(LogLevel level, object obj) {
+ if (IsEnabled(level))
+ WriteToTargets(level, "{0}", new object[] { obj } );
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the specified level.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Log(LogLevel level, IFormatProvider formatProvider, object obj) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, "{0}", new object[] { obj }, null);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message and exception at the specified level.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ /// <param name="exception">An exception to be logged.</param>
+ public void LogException(LogLevel level, string message, Exception exception) {
+ if (IsEnabled(level))
+ WriteToTargets(level, null, message, null, exception);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified parameters and formatting them with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, params object[] args) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, args, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified parameters.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Log(LogLevel level, string message, params object[] args) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, args);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified parameters.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ public void Log(LogLevel level, string message, System.Object arg1, System.Object arg2) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { arg1, arg2 });
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified parameters.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ /// <param name="arg3">Third argument to format.</param>
+ public void Log(LogLevel level, string message, System.Object arg1, System.Object arg2, System.Object arg3) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { arg1, arg2, arg3 });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Boolean" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, System.Boolean argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Boolean" /> as a parameter.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Log(LogLevel level, string message, System.Boolean argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Char" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, System.Char argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Char" /> as a parameter.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Log(LogLevel level, string message, System.Char argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Byte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, System.Byte argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Byte" /> as a parameter.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Log(LogLevel level, string message, System.Byte argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.String" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, System.String argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.String" /> as a parameter.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Log(LogLevel level, string message, System.String argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Int32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, System.Int32 argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Int32" /> as a parameter.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Log(LogLevel level, string message, System.Int32 argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Int64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, System.Int64 argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Int64" /> as a parameter.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Log(LogLevel level, string message, System.Int64 argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Single" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, System.Single argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Single" /> as a parameter.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Log(LogLevel level, string message, System.Single argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Double" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, System.Double argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Double" /> as a parameter.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Log(LogLevel level, string message, System.Double argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Decimal" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, System.Decimal argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Decimal" /> as a parameter.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Log(LogLevel level, string message, System.Decimal argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Object" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, System.Object argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.Object" /> as a parameter.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Log(LogLevel level, string message, System.Object argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.SByte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, System.SByte argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.SByte" /> as a parameter.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Log(LogLevel level, string message, System.SByte argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.UInt32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, System.UInt32 argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.UInt32" /> as a parameter.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Log(LogLevel level, string message, System.UInt32 argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.UInt64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Log(LogLevel level, IFormatProvider formatProvider, string message, System.UInt64 argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the specified level using the specified <see cref="T:System.UInt64" /> as a parameter.
+ /// </summary>
+ /// <param name="level">the log level.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Log(LogLevel level, string message, System.UInt64 argument) {
+ if (IsEnabled(level))
+ WriteToTargets(level, message, new object[] { argument });
+ }
+
+ #endregion
+
+
+ #region Trace() overloads
+
+ /// <overloads>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified format provider and format parameters.
+ /// </overloads>
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ public void Trace(string message) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level.
+ /// </summary>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Trace(object obj) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, "{0}", new object[] { obj } );
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Trace(IFormatProvider formatProvider, object obj) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, "{0}", new object[] { obj }, null);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message and exception at the <c>Trace</c> level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ /// <param name="exception">An exception to be logged.</param>
+ public void TraceException(string message, Exception exception) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, null, message, null, exception);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified parameters and formatting them with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Trace(IFormatProvider formatProvider, string message, params object[] args) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, args, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Trace(string message, params object[] args) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, args);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ public void Trace(string message, System.Object arg1, System.Object arg2) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { arg1, arg2 });
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ /// <param name="arg3">Third argument to format.</param>
+ public void Trace(string message, System.Object arg1, System.Object arg2, System.Object arg3) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { arg1, arg2, arg3 });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Boolean" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Trace(IFormatProvider formatProvider, string message, System.Boolean argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Boolean" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Trace(string message, System.Boolean argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Char" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Trace(IFormatProvider formatProvider, string message, System.Char argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Char" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Trace(string message, System.Char argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Byte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Trace(IFormatProvider formatProvider, string message, System.Byte argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Byte" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Trace(string message, System.Byte argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.String" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Trace(IFormatProvider formatProvider, string message, System.String argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.String" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Trace(string message, System.String argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Int32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Trace(IFormatProvider formatProvider, string message, System.Int32 argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Int32" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Trace(string message, System.Int32 argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Int64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Trace(IFormatProvider formatProvider, string message, System.Int64 argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Int64" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Trace(string message, System.Int64 argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Single" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Trace(IFormatProvider formatProvider, string message, System.Single argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Single" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Trace(string message, System.Single argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Double" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Trace(IFormatProvider formatProvider, string message, System.Double argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Double" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Trace(string message, System.Double argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Decimal" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Trace(IFormatProvider formatProvider, string message, System.Decimal argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Decimal" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Trace(string message, System.Decimal argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Object" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Trace(IFormatProvider formatProvider, string message, System.Object argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.Object" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Trace(string message, System.Object argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.SByte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Trace(IFormatProvider formatProvider, string message, System.SByte argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.SByte" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Trace(string message, System.SByte argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.UInt32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Trace(IFormatProvider formatProvider, string message, System.UInt32 argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.UInt32" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Trace(string message, System.UInt32 argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.UInt64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Trace(IFormatProvider formatProvider, string message, System.UInt64 argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Trace</c> level using the specified <see cref="T:System.UInt64" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Trace(string message, System.UInt64 argument) {
+ if (IsTraceEnabled)
+ WriteToTargets(LogLevel.Trace, message, new object[] { argument });
+ }
+
+ #endregion
+
+
+ #region Debug() overloads
+
+ /// <overloads>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified format provider and format parameters.
+ /// </overloads>
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ public void Debug(string message) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level.
+ /// </summary>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Debug(object obj) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, "{0}", new object[] { obj } );
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Debug(IFormatProvider formatProvider, object obj) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, "{0}", new object[] { obj }, null);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message and exception at the <c>Debug</c> level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ /// <param name="exception">An exception to be logged.</param>
+ public void DebugException(string message, Exception exception) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, null, message, null, exception);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified parameters and formatting them with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Debug(IFormatProvider formatProvider, string message, params object[] args) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, args, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Debug(string message, params object[] args) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, args);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ public void Debug(string message, System.Object arg1, System.Object arg2) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { arg1, arg2 });
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ /// <param name="arg3">Third argument to format.</param>
+ public void Debug(string message, System.Object arg1, System.Object arg2, System.Object arg3) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { arg1, arg2, arg3 });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Boolean" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Debug(IFormatProvider formatProvider, string message, System.Boolean argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Boolean" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Debug(string message, System.Boolean argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Char" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Debug(IFormatProvider formatProvider, string message, System.Char argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Char" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Debug(string message, System.Char argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Byte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Debug(IFormatProvider formatProvider, string message, System.Byte argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Byte" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Debug(string message, System.Byte argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.String" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Debug(IFormatProvider formatProvider, string message, System.String argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.String" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Debug(string message, System.String argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Int32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Debug(IFormatProvider formatProvider, string message, System.Int32 argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Int32" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Debug(string message, System.Int32 argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Int64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Debug(IFormatProvider formatProvider, string message, System.Int64 argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Int64" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Debug(string message, System.Int64 argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Single" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Debug(IFormatProvider formatProvider, string message, System.Single argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Single" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Debug(string message, System.Single argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Double" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Debug(IFormatProvider formatProvider, string message, System.Double argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Double" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Debug(string message, System.Double argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Decimal" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Debug(IFormatProvider formatProvider, string message, System.Decimal argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Decimal" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Debug(string message, System.Decimal argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Object" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Debug(IFormatProvider formatProvider, string message, System.Object argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.Object" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Debug(string message, System.Object argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.SByte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Debug(IFormatProvider formatProvider, string message, System.SByte argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.SByte" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Debug(string message, System.SByte argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.UInt32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Debug(IFormatProvider formatProvider, string message, System.UInt32 argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.UInt32" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Debug(string message, System.UInt32 argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.UInt64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Debug(IFormatProvider formatProvider, string message, System.UInt64 argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Debug</c> level using the specified <see cref="T:System.UInt64" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Debug(string message, System.UInt64 argument) {
+ if (IsDebugEnabled)
+ WriteToTargets(LogLevel.Debug, message, new object[] { argument });
+ }
+
+ #endregion
+
+
+ #region Info() overloads
+
+ /// <overloads>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified format provider and format parameters.
+ /// </overloads>
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ public void Info(string message) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level.
+ /// </summary>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Info(object obj) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, "{0}", new object[] { obj } );
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Info(IFormatProvider formatProvider, object obj) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, "{0}", new object[] { obj }, null);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message and exception at the <c>Info</c> level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ /// <param name="exception">An exception to be logged.</param>
+ public void InfoException(string message, Exception exception) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, null, message, null, exception);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified parameters and formatting them with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Info(IFormatProvider formatProvider, string message, params object[] args) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, args, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Info(string message, params object[] args) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, args);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ public void Info(string message, System.Object arg1, System.Object arg2) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { arg1, arg2 });
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ /// <param name="arg3">Third argument to format.</param>
+ public void Info(string message, System.Object arg1, System.Object arg2, System.Object arg3) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { arg1, arg2, arg3 });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Boolean" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Info(IFormatProvider formatProvider, string message, System.Boolean argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Boolean" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Info(string message, System.Boolean argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Char" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Info(IFormatProvider formatProvider, string message, System.Char argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Char" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Info(string message, System.Char argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Byte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Info(IFormatProvider formatProvider, string message, System.Byte argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Byte" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Info(string message, System.Byte argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.String" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Info(IFormatProvider formatProvider, string message, System.String argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.String" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Info(string message, System.String argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Int32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Info(IFormatProvider formatProvider, string message, System.Int32 argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Int32" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Info(string message, System.Int32 argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Int64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Info(IFormatProvider formatProvider, string message, System.Int64 argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Int64" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Info(string message, System.Int64 argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Single" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Info(IFormatProvider formatProvider, string message, System.Single argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Single" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Info(string message, System.Single argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Double" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Info(IFormatProvider formatProvider, string message, System.Double argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Double" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Info(string message, System.Double argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Decimal" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Info(IFormatProvider formatProvider, string message, System.Decimal argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Decimal" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Info(string message, System.Decimal argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Object" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Info(IFormatProvider formatProvider, string message, System.Object argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.Object" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Info(string message, System.Object argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.SByte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Info(IFormatProvider formatProvider, string message, System.SByte argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.SByte" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Info(string message, System.SByte argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.UInt32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Info(IFormatProvider formatProvider, string message, System.UInt32 argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.UInt32" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Info(string message, System.UInt32 argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.UInt64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Info(IFormatProvider formatProvider, string message, System.UInt64 argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Info</c> level using the specified <see cref="T:System.UInt64" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Info(string message, System.UInt64 argument) {
+ if (IsInfoEnabled)
+ WriteToTargets(LogLevel.Info, message, new object[] { argument });
+ }
+
+ #endregion
+
+
+ #region Warn() overloads
+
+ /// <overloads>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified format provider and format parameters.
+ /// </overloads>
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ public void Warn(string message) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level.
+ /// </summary>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Warn(object obj) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, "{0}", new object[] { obj } );
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Warn(IFormatProvider formatProvider, object obj) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, "{0}", new object[] { obj }, null);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message and exception at the <c>Warn</c> level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ /// <param name="exception">An exception to be logged.</param>
+ public void WarnException(string message, Exception exception) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, null, message, null, exception);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified parameters and formatting them with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Warn(IFormatProvider formatProvider, string message, params object[] args) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, args, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Warn(string message, params object[] args) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, args);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ public void Warn(string message, System.Object arg1, System.Object arg2) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { arg1, arg2 });
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ /// <param name="arg3">Third argument to format.</param>
+ public void Warn(string message, System.Object arg1, System.Object arg2, System.Object arg3) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { arg1, arg2, arg3 });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Boolean" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Warn(IFormatProvider formatProvider, string message, System.Boolean argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Boolean" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Warn(string message, System.Boolean argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Char" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Warn(IFormatProvider formatProvider, string message, System.Char argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Char" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Warn(string message, System.Char argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Byte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Warn(IFormatProvider formatProvider, string message, System.Byte argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Byte" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Warn(string message, System.Byte argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.String" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Warn(IFormatProvider formatProvider, string message, System.String argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.String" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Warn(string message, System.String argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Int32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Warn(IFormatProvider formatProvider, string message, System.Int32 argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Int32" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Warn(string message, System.Int32 argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Int64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Warn(IFormatProvider formatProvider, string message, System.Int64 argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Int64" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Warn(string message, System.Int64 argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Single" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Warn(IFormatProvider formatProvider, string message, System.Single argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Single" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Warn(string message, System.Single argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Double" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Warn(IFormatProvider formatProvider, string message, System.Double argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Double" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Warn(string message, System.Double argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Decimal" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Warn(IFormatProvider formatProvider, string message, System.Decimal argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Decimal" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Warn(string message, System.Decimal argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Object" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Warn(IFormatProvider formatProvider, string message, System.Object argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.Object" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Warn(string message, System.Object argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.SByte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Warn(IFormatProvider formatProvider, string message, System.SByte argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.SByte" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Warn(string message, System.SByte argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.UInt32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Warn(IFormatProvider formatProvider, string message, System.UInt32 argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.UInt32" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Warn(string message, System.UInt32 argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.UInt64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Warn(IFormatProvider formatProvider, string message, System.UInt64 argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Warn</c> level using the specified <see cref="T:System.UInt64" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Warn(string message, System.UInt64 argument) {
+ if (IsWarnEnabled)
+ WriteToTargets(LogLevel.Warn, message, new object[] { argument });
+ }
+
+ #endregion
+
+
+ #region Error() overloads
+
+ /// <overloads>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified format provider and format parameters.
+ /// </overloads>
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ public void Error(string message) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level.
+ /// </summary>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Error(object obj) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, "{0}", new object[] { obj } );
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Error(IFormatProvider formatProvider, object obj) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, "{0}", new object[] { obj }, null);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message and exception at the <c>Error</c> level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ /// <param name="exception">An exception to be logged.</param>
+ public void ErrorException(string message, Exception exception) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, null, message, null, exception);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified parameters and formatting them with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Error(IFormatProvider formatProvider, string message, params object[] args) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, args, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Error(string message, params object[] args) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, args);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ public void Error(string message, System.Object arg1, System.Object arg2) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { arg1, arg2 });
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ /// <param name="arg3">Third argument to format.</param>
+ public void Error(string message, System.Object arg1, System.Object arg2, System.Object arg3) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { arg1, arg2, arg3 });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Boolean" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Error(IFormatProvider formatProvider, string message, System.Boolean argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Boolean" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Error(string message, System.Boolean argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Char" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Error(IFormatProvider formatProvider, string message, System.Char argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Char" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Error(string message, System.Char argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Byte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Error(IFormatProvider formatProvider, string message, System.Byte argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Byte" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Error(string message, System.Byte argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.String" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Error(IFormatProvider formatProvider, string message, System.String argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.String" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Error(string message, System.String argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Int32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Error(IFormatProvider formatProvider, string message, System.Int32 argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Int32" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Error(string message, System.Int32 argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Int64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Error(IFormatProvider formatProvider, string message, System.Int64 argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Int64" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Error(string message, System.Int64 argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Single" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Error(IFormatProvider formatProvider, string message, System.Single argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Single" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Error(string message, System.Single argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Double" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Error(IFormatProvider formatProvider, string message, System.Double argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Double" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Error(string message, System.Double argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Decimal" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Error(IFormatProvider formatProvider, string message, System.Decimal argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Decimal" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Error(string message, System.Decimal argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Object" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Error(IFormatProvider formatProvider, string message, System.Object argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.Object" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Error(string message, System.Object argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.SByte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Error(IFormatProvider formatProvider, string message, System.SByte argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.SByte" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Error(string message, System.SByte argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.UInt32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Error(IFormatProvider formatProvider, string message, System.UInt32 argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.UInt32" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Error(string message, System.UInt32 argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.UInt64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Error(IFormatProvider formatProvider, string message, System.UInt64 argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Error</c> level using the specified <see cref="T:System.UInt64" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Error(string message, System.UInt64 argument) {
+ if (IsErrorEnabled)
+ WriteToTargets(LogLevel.Error, message, new object[] { argument });
+ }
+
+ #endregion
+
+
+ #region Fatal() overloads
+
+ /// <overloads>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified format provider and format parameters.
+ /// </overloads>
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ public void Fatal(string message) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level.
+ /// </summary>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Fatal(object obj) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, "{0}", new object[] { obj } );
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void Fatal(IFormatProvider formatProvider, object obj) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, "{0}", new object[] { obj }, null);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message and exception at the <c>Fatal</c> level.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ /// <param name="exception">An exception to be logged.</param>
+ public void FatalException(string message, Exception exception) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, null, message, null, exception);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified parameters and formatting them with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Fatal(IFormatProvider formatProvider, string message, params object[] args) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, args, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void Fatal(string message, params object[] args) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, args);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ public void Fatal(string message, System.Object arg1, System.Object arg2) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { arg1, arg2 });
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified parameters.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ /// <param name="arg3">Third argument to format.</param>
+ public void Fatal(string message, System.Object arg1, System.Object arg2, System.Object arg3) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { arg1, arg2, arg3 });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Boolean" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Fatal(IFormatProvider formatProvider, string message, System.Boolean argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Boolean" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Boolean" /> argument to format.</param>
+ public void Fatal(string message, System.Boolean argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Char" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Fatal(IFormatProvider formatProvider, string message, System.Char argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Char" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Char" /> argument to format.</param>
+ public void Fatal(string message, System.Char argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Byte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Fatal(IFormatProvider formatProvider, string message, System.Byte argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Byte" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Byte" /> argument to format.</param>
+ public void Fatal(string message, System.Byte argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.String" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Fatal(IFormatProvider formatProvider, string message, System.String argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.String" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.String" /> argument to format.</param>
+ public void Fatal(string message, System.String argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Int32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Fatal(IFormatProvider formatProvider, string message, System.Int32 argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Int32" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int32" /> argument to format.</param>
+ public void Fatal(string message, System.Int32 argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Int64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Fatal(IFormatProvider formatProvider, string message, System.Int64 argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Int64" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Int64" /> argument to format.</param>
+ public void Fatal(string message, System.Int64 argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Single" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Fatal(IFormatProvider formatProvider, string message, System.Single argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Single" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Single" /> argument to format.</param>
+ public void Fatal(string message, System.Single argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Double" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Fatal(IFormatProvider formatProvider, string message, System.Double argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Double" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Double" /> argument to format.</param>
+ public void Fatal(string message, System.Double argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Decimal" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Fatal(IFormatProvider formatProvider, string message, System.Decimal argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Decimal" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Decimal" /> argument to format.</param>
+ public void Fatal(string message, System.Decimal argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Object" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Fatal(IFormatProvider formatProvider, string message, System.Object argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.Object" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.Object" /> argument to format.</param>
+ public void Fatal(string message, System.Object argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.SByte" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Fatal(IFormatProvider formatProvider, string message, System.SByte argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.SByte" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.SByte" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Fatal(string message, System.SByte argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.UInt32" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Fatal(IFormatProvider formatProvider, string message, System.UInt32 argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.UInt32" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt32" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Fatal(string message, System.UInt32 argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { argument });
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.UInt64" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Fatal(IFormatProvider formatProvider, string message, System.UInt64 argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the <c>Fatal</c> level using the specified <see cref="T:System.UInt64" /> as a parameter.
+ /// </summary>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:System.UInt64" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void Fatal(string message, System.UInt64 argument) {
+ if (IsFatalEnabled)
+ WriteToTargets(LogLevel.Fatal, message, new object[] { argument });
+ }
+
+ #endregion
+
+ // end of generated code
+ }
+}
diff --git a/src/NLog/LoggerImpl.cs b/src/NLog/LoggerImpl.cs
new file mode 100644
index 0000000..aa79cdc
--- /dev/null
+++ b/src/NLog/LoggerImpl.cs
@@ -0,0 +1,143 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.Reflection;
+
+using NLog.Filters;
+using NLog.Targets;
+using NLog.Internal;
+
+namespace NLog
+{
+ internal sealed class LoggerImpl
+ {
+ private LoggerImpl() { }
+
+ private const int STACK_TRACE_SKIP_METHODS = 0;
+
+ internal static void Write(Type loggerType, TargetWithFilterChain targets, LogEventInfo logEvent, LogFactory factory)
+ {
+ if (targets == null)
+ return;
+
+#if !NETCF
+ bool needTrace = false;
+ bool needTraceSources = false;
+
+ int nst = targets.NeedsStackTrace;
+
+ if (nst > 0)
+ needTrace = true;
+ if (nst > 1)
+ needTraceSources = true;
+
+ StackTrace stackTrace = null;
+ if (needTrace && !logEvent.HasStackTrace)
+ {
+ int firstUserFrame = 0;
+ stackTrace = new StackTrace(STACK_TRACE_SKIP_METHODS, needTraceSources);
+
+ for (int i = 0; i < stackTrace.FrameCount; ++i)
+ {
+ System.Reflection.MethodBase mb = stackTrace.GetFrame(i).GetMethod();
+
+ if (mb.DeclaringType == loggerType)
+ {
+ firstUserFrame = i + 1;
+ }
+ else
+ {
+ if (firstUserFrame != 0)
+ break;
+ }
+ }
+ logEvent.SetStackTrace(stackTrace, firstUserFrame);
+ }
+#endif
+ for (TargetWithFilterChain awf = targets; awf != null; awf = awf.Next)
+ {
+ Target app = awf.Target;
+ FilterResult result = FilterResult.Neutral;
+
+ try
+ {
+ FilterCollection filterChain = awf.FilterChain;
+
+ for (int i = 0; i < filterChain.Count; ++i)
+ {
+ Filter f = filterChain[i];
+ result = f.Check(logEvent);
+ if (result != FilterResult.Neutral)
+ break;
+ }
+ if ((result == FilterResult.Ignore) || (result == FilterResult.IgnoreFinal))
+ {
+ if (InternalLogger.IsDebugEnabled)
+ {
+ InternalLogger.Debug("{0}.{1} Rejecting message because of a filter.", logEvent.LoggerName, logEvent.Level);
+ }
+ if (result == FilterResult.IgnoreFinal)
+ return;
+ continue;
+ }
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("FilterChain exception: {0}", ex);
+ if (factory.ThrowExceptions)
+ throw;
+ else
+ continue;
+ }
+
+ try
+ {
+ app.Write(logEvent);
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Target exception: {0}", ex);
+ if (factory.ThrowExceptions)
+ throw;
+ else
+ continue;
+ }
+ if (result == FilterResult.LogFinal)
+ return;
+ }
+ }
+ }
+}
diff --git a/src/NLog/MDC.cs b/src/NLog/MDC.cs
new file mode 100644
index 0000000..de0f3d8
--- /dev/null
+++ b/src/NLog/MDC.cs
@@ -0,0 +1,124 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+
+namespace NLog
+{
+ /// <summary>
+ /// Mapped Diagnostics Context - a thread-local structure that keeps a dictionary
+ /// of strings and provides methods to output them in layouts.
+ /// Mostly for compatibility with log4net.
+ /// </summary>
+ public sealed class MDC
+ {
+ private MDC(){}
+
+ /// <summary>
+ /// Sets the current thread MDC item to the specified value.
+ /// </summary>
+ /// <param name="item">Item name.</param>
+ /// <param name="value">Item value.</param>
+ public static void Set(string item, string value)
+ {
+ IDictionary dict = GetThreadDictionary();
+
+ dict[item] = value;
+ }
+
+ /// <summary>
+ /// Gets the current thread MDC named item.
+ /// </summary>
+ /// <param name="item">Item name.</param>
+ /// <returns>The item value of String.Empty if the value is not present.</returns>
+ public static string Get(string item)
+ {
+ IDictionary dict = GetThreadDictionary();
+
+ string s = (string)dict[item];
+ if (s == null)
+ return String.Empty;
+ else
+ return s;
+ }
+
+ /// <summary>
+ /// Checks whether the specified item exists in current thread MDC.
+ /// </summary>
+ /// <param name="item">Item name.</param>
+ /// <returns>A boolean indicating whether the specified item exists in current thread MDC.</returns>
+ public static bool Contains(string item)
+ {
+ IDictionary dict = GetThreadDictionary();
+
+ return dict.Contains(item);
+ }
+
+ /// <summary>
+ /// Removes the specified item from current thread MDC.
+ /// </summary>
+ /// <param name="item">Item name.</param>
+ public static void Remove(string item)
+ {
+ IDictionary dict = GetThreadDictionary();
+
+ dict.Remove(item);
+ }
+
+ /// <summary>
+ /// Clears the content of current thread MDC.
+ /// </summary>
+ public static void Clear()
+ {
+ IDictionary dict = GetThreadDictionary();
+
+ dict.Clear();
+ }
+
+ internal static IDictionary GetThreadDictionary()
+ {
+ IDictionary threadDictionary = (IDictionary)System.Threading.Thread.GetData(_dataSlot);
+
+ if (threadDictionary == null)
+ {
+ threadDictionary = new Hashtable();
+ System.Threading.Thread.SetData(_dataSlot, threadDictionary);
+ }
+
+ return threadDictionary;
+ }
+
+ private static LocalDataStoreSlot _dataSlot = System.Threading.Thread.AllocateDataSlot();
+ }
+}
diff --git a/src/NLog/NDC.cs b/src/NLog/NDC.cs
new file mode 100644
index 0000000..5ece5b5
--- /dev/null
+++ b/src/NLog/NDC.cs
@@ -0,0 +1,233 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Text;
+
+namespace NLog
+{
+ /// <summary>
+ /// Nested Diagnostics Context - a thread-local structure that keeps a stack
+ /// of strings and provides methods to output them in layouts
+ /// Mostly for compatibility with log4net.
+ /// </summary>
+ public sealed class NDC
+ {
+ private NDC(){}
+
+ /// <summary>
+ /// Pushes the specified text on current thread NDC.
+ /// </summary>
+ /// <param name="text">The text to be pushed.</param>
+ /// <returns>An instance of the object that implements IDisposable that returns the stack to the previous level when IDisposable.Dispose() is called. To be used with C# using() statement.</returns>
+ public static IDisposable Push(string text)
+ {
+ StringCollection stack = GetThreadStack();
+ int previousCount = stack.Count;
+ stack.Add(text);
+ return new StackPopper(stack, previousCount);
+ }
+
+ /// <summary>
+ /// Pops the top message off the NDC stack.
+ /// </summary>
+ /// <returns>The top message which is no longer on the stack.</returns>
+ public static string Pop()
+ {
+ StringCollection stack = GetThreadStack();
+ if (stack.Count > 0)
+ {
+ string retVal = (string)stack[stack.Count - 1];
+ stack.RemoveAt(stack.Count - 1);
+ return retVal;
+ }
+ else
+ {
+ return String.Empty;
+ }
+ }
+
+ /// <summary>
+ /// Gets the top NDC message but doesn't remove it.
+ /// </summary>
+ /// <returns>The top message. </returns>
+ public static string GetTopMessage()
+ {
+ StringCollection stack = GetThreadStack();
+ if (stack.Count > 0)
+ {
+ return (string)stack[stack.Count - 1];
+ }
+ else
+ {
+ return String.Empty;
+ }
+ }
+
+ /// <summary>
+ /// Clears current thread NDC stack.
+ /// </summary>
+ public static void Clear()
+ {
+ StringCollection stack = GetThreadStack();
+
+ stack.Clear();
+ }
+
+ /// <summary>
+ /// Gets all messages on the stack separated by the specified separator.
+ /// </summary>
+ /// <param name="separator">The separator.</param>
+ /// <returns>Messages on the stack concatenated using the specified separator.</returns>
+ public static string GetAllMessages(string separator)
+ {
+ StringCollection stack = GetThreadStack();
+ if (stack.Count == 0)
+ return String.Empty;
+
+ if (stack.Count == 1)
+ return GetTopMessage();
+
+ int totalLength = ((string)stack[0]).Length;
+ for (int i = 1; i < stack.Count; ++i)
+ {
+ totalLength += separator.Length;
+ }
+ StringBuilder sb = new StringBuilder(totalLength);
+ sb.Append((string)stack[0]);
+ for (int i = 1; i < stack.Count; ++i)
+ {
+ sb.Append(separator);
+ sb.Append((string)stack[i]);
+ }
+ return sb.ToString();
+ }
+
+ /// <summary>
+ /// Calculates the string representing <c>count</c> bottommost messages using the specified separator.
+ /// </summary>
+ /// <param name="count">Number of bottom messages to be returned</param>
+ /// <param name="separator">The separator</param>
+ /// <returns>A string representing <c>count</c> bottommost messages using the specified separator.</returns>
+ public static string GetBottomMessages(int count, string separator)
+ {
+ StringCollection stack = GetThreadStack();
+ if (count > stack.Count)
+ count = stack.Count;
+ if (count == 0)
+ return String.Empty;
+
+ if (count == 1)
+ return ((string)stack[0]);
+
+ int totalLength = ((string)stack[0]).Length;
+ for (int i = 1; i < count; ++i)
+ {
+ totalLength += separator.Length;
+ }
+ StringBuilder sb = new StringBuilder(totalLength);
+ sb.Append((string)stack[0]);
+ for (int i = 1; i < count; ++i)
+ {
+ sb.Append(separator);
+ sb.Append((string)stack[i]);
+ }
+ return sb.ToString();
+ }
+
+ /// <summary>
+ /// Calculates the string representing <c>count</c> topmost messages using the specified separator.
+ /// </summary>
+ /// <param name="count">Number of topmost messages to be returned</param>
+ /// <param name="separator">The separator</param>
+ /// <returns>A string representing <c>count</c> topmost messages using the specified separator.</returns>
+ public static string GetTopMessages(int count, string separator)
+ {
+ StringCollection stack = GetThreadStack();
+ if (count >= stack.Count)
+ return GetAllMessages(separator);
+
+ int pos0 = stack.Count - count;
+ int totalLength = ((string)stack[pos0]).Length;
+ for (int i = pos0 + 1; i < stack.Count; ++i)
+ {
+ totalLength += separator.Length;
+ }
+ StringBuilder sb = new StringBuilder(totalLength);
+ sb.Append((string)stack[pos0]);
+ for (int i = pos0 + 1; i < stack.Count; ++i)
+ {
+ sb.Append(separator);
+ sb.Append((string)stack[i]);
+ }
+ return sb.ToString();
+ }
+
+ private static StringCollection GetThreadStack()
+ {
+ StringCollection threadStack = (StringCollection)System.Threading.Thread.GetData(_dataSlot);
+
+ if (threadStack == null)
+ {
+ threadStack = new StringCollection();
+ System.Threading.Thread.SetData(_dataSlot, threadStack);
+ }
+
+ return threadStack;
+ }
+
+ private class StackPopper: IDisposable
+ {
+ private StringCollection _stack;
+ private int _previousCount;
+
+ public StackPopper(StringCollection stack, int previousCount)
+ {
+ _stack = stack;
+ _previousCount = previousCount;
+ }
+
+ void IDisposable.Dispose()
+ {
+ while (_stack.Count > _previousCount)
+ {
+ _stack.RemoveAt(_stack.Count - 1);
+ }
+ }
+ }
+
+ private static LocalDataStoreSlot _dataSlot = System.Threading.Thread.AllocateDataSlot();
+ }
+}
diff --git a/src/NLog/NLog.vs2003.csdproj b/src/NLog/NLog.vs2003.csdproj
new file mode 100644
index 0000000..78de83d
--- /dev/null
+++ b/src/NLog/NLog.vs2003.csdproj
@@ -0,0 +1,262 @@
+<VisualStudioProject>
+ <ECSHARP ProjectType="Local" ProductVersion="7.10.3077" SchemaVersion="1.0" ProjectGuid="{4125C120-539F-4C80-B3D2-35FFF271998A}">
+ <Build>
+ <Settings ApplicationIcon="" AssemblyKeyContainerName="" AssemblyName="NLog" AssemblyOriginatorKeyFile="" DelaySign="false" OutputType="Library" OutputFileFolder="\Program Files\NLog" RootNamespace="NLog" StartupObject="">
+ <Platform Name="Windows CE" />
+ <Config Name="Debug|Windows CE" AllowUnsafeBlocks="false" BaseAddress="0" CheckForOverflowUnderflow="false" ConfigurationOverrideFile="" DefineConstants="DEBUG;TRACE;NETCF;NETCF_1_0" DocumentationFile="" DebugSymbols="true" FileAlignment="4096" IncrementalBuild="false" Optimize="false" OutputPath="bin\DebugCF\" RegisterForComInterop="false" RemoveIntegerChecks="false" TreatWarningsAsErrors="false" WarningLevel="4" />
+ <Config Name="Release|Windows CE" AllowUnsafeBlocks="false" BaseAddress="0" CheckForOverflowUnderflow="false" ConfigurationOverrideFile="" DefineConstants="TRACE;NETCF;NETCF_1_0" DocumentationFile="" DebugSymbols="false" FileAlignment="4096" IncrementalBuild="false" Optimize="true" OutputPath="bin\ReleaseCF\" RegisterForComInterop="false" RemoveIntegerChecks="false" TreatWarningsAsErrors="false" WarningLevel="4" />
+ </Settings>
+ <References>
+ <Reference Platform="Windows CE" Name="MSCorLib" AssemblyName="mscorlib" Private="False" />
+ <Reference Platform="Windows CE" Name="System" AssemblyName="System" Private="False" />
+ <Reference Platform="Windows CE" Name="System.Drawing" AssemblyName="System.Drawing" Private="False" />
+ <Reference Platform="Windows CE" Name="System.Windows.Forms" AssemblyName="System.Windows.Forms" Private="False" />
+ <Reference Platform="Windows CE" Name="System.XML" AssemblyName="System.Xml" Private="False" />
+ <Reference Platform="Windows CE" Name="System.Data" AssemblyName="System.Data" Private="False" />
+ <Reference Platform="Windows CE" Name="System.Web.Services" AssemblyName="System.Web.Services" />
+ <Reference Platform="Windows CE-Designer" Name="System.CF.Design" AssemblyName="System.CF.Design" Private="False" />
+ <Reference Platform="Windows CE-Designer" Name="System.CF.Design.UI" AssemblyName="System.CF.Design.UI" Private="False" />
+ <Reference Platform="Windows CE-Designer" Name="System.CF.Windows.Forms" AssemblyName="System.CF.Windows.Forms" Private="False" />
+ <Reference Platform="Windows CE-Designer" Name="System.CF.Drawing" AssemblyName="System.CF.Drawing" Private="False" />
+ <Reference Platform="Windows CE-Designer" Name="System" AssemblyName="System" Private="False" />
+ </References>
+ </Build>
+ <Files>
+ <Include>
+ <File RelPath="AssemblyInfo.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="AssemblySign.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="ConditionMethodAttribute.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="ConditionMethodFactory.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="ConditionMethodsAttribute.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Filter.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="FilterAttribute.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="FilterCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="FilterFactory.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="FilterResult.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="GDC.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="ILayout.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Layout.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutAttribute.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutFactory.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderer.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRendererAttribute.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRendererCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRendererFactory.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LogEventInfo.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Logger.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LoggerImpl.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LogLevel.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LogManager.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="MDC.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="NDC.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Target.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="TargetAttribute.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="TargetCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="TargetFactory.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="TargetWithLayout.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionAndExpression.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionExpression.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionExpressionCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionLayoutExpression.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionLevelExpression.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionLiteralExpression.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionLoggerNameExpression.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionMessageExpression.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionMethodExpression.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionMethods.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionNotExpression.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionOrExpression.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionParseException.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionParser.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionRelationalExpression.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionRelationalOperator.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionTokenizer.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Conditions\ConditionTokenType.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\LoggingRule.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\LoggingRuleCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\NotSupportedRuntimeAttribute.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\RequiredParameterAttribute.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\RuntimeFramework.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\RuntimeOS.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\SimpleConfigurator.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\SupportedRuntimeAttribute.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\SupportedRuntimeAttributeBase.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\XmlLoggingConfiguration.cs" SubType="Code" BuildAction="Compile" />
+ <Folder RelPath="DotNet\" />
+ <File RelPath="Filters\ConditionBasedFilter.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Filters\LayoutBasedFilter.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Filters\WhenContains.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Filters\WhenEqual.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Filters\WhenNotContains.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Filters\WhenNotEqual.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\CompactFrameworkHelper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\DictionaryBase.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\EnvironmentHelper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\ExtensionUtils.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\FactoryHelper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\FileInfoHelper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\FilterDictionary.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\FormHelper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\HttpUtility.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\InternalLogger.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\LayoutRendererDictionary.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\LogEventInfoBuffer.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\LoggerConfiguration.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\LoggerDictionary.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\MethodInfoDictionary.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\MultiFileWatcher.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\PlatformDetector.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\PropertyHelper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\PropertyInfoDictionary.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\StringCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\StringDictionary.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\TargetDictionary.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\TargetWithFilterChain.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\ThreadIDHelper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\TypeDictionary.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\TypeToPropertyInfoDictionaryAssociation.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\FileAppenders\BaseFileAppender.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\FileAppenders\CountingSingleProcessFileAppender.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\FileAppenders\ICreateFile.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\FileAppenders\IFileAppenderFactory.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\FileAppenders\MutexMultiProcessFileAppender.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\FileAppenders\RetryingMultiProcessFileAppender.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\FileAppenders\SingleProcessFileAppender.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\FileAppenders\UnixMultiProcessFileAppender.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\NetworkSenders\NetworkSender.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\NetworkSenders\TcpNetworkSender.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\NetworkSenders\UdpNetworkSender.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\Win32\Win32FileAttributes.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\Win32\Win32FileHelper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ASPNetApplication.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ASPNetRequest.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ASPNetSession.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ASPNetSessionID.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ASPNetUserAuthType.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ASPNetUserIdentity.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\BaseDir.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\CallSite.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\Counter.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\Date.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\Environment.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\Exception.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\GCD.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\Guid.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\Identity.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\Level.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\Literal.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\Log4JXmlEvent.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\LoggerName.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\LongDate.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\MachineName.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\MDC.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\Message.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\NDC.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\NewLine.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\NLogDir.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\PerformanceCounter.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ProcessID.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ProcessName.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ProcessTime.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\QPC.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ShortDate.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\SpecialFolder.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\StackTrace.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\TempDir.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ThreadID.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ThreadName.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\Ticks.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Layouts\CsvColumn.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Layouts\CsvColumnCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Layouts\CsvLayout.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Layouts\CsvQuotingMode.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Layouts\Log4JXmlEventLayout.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\ASPNetTrace.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Chainsaw.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Console.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Database.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\DatabaseParameterInfo.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\DatabaseParameterInfoCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Debug.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Debugger.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\File.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\FormControl.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Mail.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Memory.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\MessageBox.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\MethodCall.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\MethodCallParameter.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\MethodCallParameterCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\MethodCallTargetBase.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Network.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\NLogViewer.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\NLogViewerParameterInfo.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\NLogViewerParameterInfoCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Null.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\RichTextBox.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\RichTextBoxRowColoringRule.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\RichTextBoxRowColoringRuleCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\RichTextBoxWordColoringRule.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\RichTextBoxWordColoringRuleCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Trace.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\WebService.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Compound\CompoundTargetBase.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Compound\FallbackTarget.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Compound\RandomizeTarget.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Compound\RoundRobinTarget.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Compound\SplitTarget.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Wrappers\ASPNetBufferingTargetWrapper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Wrappers\AsyncTargetWrapper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Wrappers\AutoFlushTargetWrapper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Wrappers\BufferingTargetWrapper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Wrappers\FilteringRule.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Wrappers\FilteringRuleCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Wrappers\FilteringWrapper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Wrappers\PostFilteringWrapper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Wrappers\RepeatTargetWrapper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Wrappers\RetryTargetWrapper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Wrappers\WrapperTargetBase.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Web\NLogHttpModule.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\ASPHelper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\LayoutRenderers\ASPApplication.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\LayoutRenderers\ASPRequest.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\LayoutRenderers\ASPSession.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\LayoutRenderers\Registry.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\LayoutRenderers\WindowsIdentity.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\Targets\ASPResponse.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\Targets\ColoredConsole.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\Targets\ConsoleOutputColor.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\Targets\ConsoleRowHighlightingRule.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\Targets\ConsoleRowHighlightingRuleCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\Targets\ConsoleWin32Api.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\Targets\ConsoleWordHighlightingRule.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\Targets\ConsoleWordHighlightingRuleCollection.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\Targets\EventLog.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\Targets\MSMQ.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\Targets\OutputDebugString.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Win32\Targets\PerfCounterTarget.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\ConfigSectionHandler.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\ArrayParameterAttribute.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\AcceptsConditionAttribute.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\AcceptsLayoutAttribute.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\LoggingConfiguration.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LogFactory.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\Wrappers\ImpersonatingWrapper.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Internal\CurrentTimeGetter.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ProcessInfo.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\GC.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="ILayoutWithHeaderAndFooter.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\NLogConfigurationException.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutParser.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\FileContents.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Config\DefaultParameterAttribute.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Layouts\LayoutWithHeaderAndFooter.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="TargetWithLayoutHeaderAndFooter.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\EventContext.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\Rot13.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="AssemblyBuildInfo.cs" SubType="Code" BuildAction="Compile" />
+ </Include>
+ </Files>
+ </ECSHARP>
+</VisualStudioProject>
\ No newline at end of file
diff --git a/src/NLog/NLog.vs2003.csproj b/src/NLog/NLog.vs2003.csproj
new file mode 100644
index 0000000..1a6ade3
--- /dev/null
+++ b/src/NLog/NLog.vs2003.csproj
@@ -0,0 +1,1278 @@
+<VisualStudioProject>
+ <CSHARP
+ ProjectType = "Local"
+ ProductVersion = "7.10.3077"
+ SchemaVersion = "2.0"
+ ProjectGuid = "{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+ >
+ <Build>
+ <Settings
+ ApplicationIcon = ""
+ AssemblyKeyContainerName = ""
+ AssemblyName = "NLog"
+ AssemblyOriginatorKeyFile = ""
+ DefaultClientScript = "JScript"
+ DefaultHTMLPageLayout = "Grid"
+ DefaultTargetSchema = "IE50"
+ DelaySign = "false"
+ OutputType = "Library"
+ PreBuildEvent = '"$(ProjectDir)..\..\tools\UpdateBuildNumber.exe" "$(ProjectDir)..\..\NLog.version" "$(ProjectDir)AssemblyBuildInfo.cs" "$(ProjectDir)..\..\build\NLog.buildversion"'
+ PostBuildEvent = ""
+ RootNamespace = "NLog"
+ RunPostBuildEvent = "OnBuildSuccess"
+ StartupObject = ""
+ >
+ <Config
+ Name = "Debug"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "DOTNET;DOTNET_1_1"
+ DocumentationFile = "NLog.xml"
+ DebugSymbols = "true"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = ""
+ Optimize = "false"
+ OutputPath = "bin\Debug\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ <Config
+ Name = "Release"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "DOTNET;DOTNET_1_1"
+ DocumentationFile = "NLog.xml"
+ DebugSymbols = "false"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = "1591"
+ Optimize = "false"
+ OutputPath = "bin\Release\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ </Settings>
+ <References>
+ <Reference
+ Name = "System.XML"
+ AssemblyName = "System.Xml"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
+ />
+ <Reference
+ Name = "System"
+ AssemblyName = "System"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll"
+ />
+ <Reference
+ Name = "system.data"
+ AssemblyName = "System.Data"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\system.data.dll"
+ />
+ <Reference
+ Name = "system.web"
+ AssemblyName = "System.Web"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\system.web.dll"
+ />
+ <Reference
+ Name = "system.web.services"
+ AssemblyName = "System.Web.Services"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\system.web.services.dll"
+ />
+ <Reference
+ Name = "system.windows.forms"
+ AssemblyName = "System.Windows.Forms"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\system.windows.forms.dll"
+ />
+ <Reference
+ Name = "System.Messaging"
+ AssemblyName = "System.Messaging"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Messaging.dll"
+ />
+ <Reference
+ Name = "System.Drawing"
+ AssemblyName = "System.Drawing"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Drawing.dll"
+ />
+ </References>
+ </Build>
+ <Files>
+ <Include>
+ <File
+ RelPath = "AssemblyBuildInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "AssemblyInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "AssemblySign.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "ConditionMethodAttribute.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "ConditionMethodFactory.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "ConditionMethodsAttribute.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Filter.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "FilterAttribute.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "FilterCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "FilterFactory.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "FilterResult.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "GDC.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "ILayout.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "ILayoutWithHeaderAndFooter.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Layout.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutAttribute.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutFactory.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutParser.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderer.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRendererAttribute.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRendererCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRendererFactory.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LogEventInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LogFactory.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Logger.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LoggerImpl.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LogLevel.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LogManager.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "MDC.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "NDC.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Target.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "TargetAttribute.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "TargetCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "TargetFactory.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "TargetWithLayout.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "TargetWithLayoutHeaderAndFooter.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionAndExpression.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionExpression.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionExpressionCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionLayoutExpression.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionLevelExpression.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionLiteralExpression.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionLoggerNameExpression.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionMessageExpression.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionMethodExpression.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionMethods.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionNotExpression.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionOrExpression.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionParseException.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionParser.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionRelationalExpression.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionRelationalOperator.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionTokenizer.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Conditions\ConditionTokenType.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\AcceptsConditionAttribute.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\AcceptsLayoutAttribute.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\ArrayParameterAttribute.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\ConfigSectionHandler.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\DefaultParameterAttribute.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\LoggingConfiguration.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\LoggingRule.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\LoggingRuleCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\NLogConfigurationException.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\NotSupportedRuntimeAttribute.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\RequiredParameterAttribute.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\RuntimeFramework.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\RuntimeOS.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\SimpleConfigurator.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\SupportedRuntimeAttribute.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\SupportedRuntimeAttributeBase.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Config\XmlLoggingConfiguration.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <Folder RelPath = "DotNet\" />
+ <File
+ RelPath = "Filters\ConditionBasedFilter.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Filters\LayoutBasedFilter.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Filters\WhenContains.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Filters\WhenEqual.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Filters\WhenNotContains.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Filters\WhenNotEqual.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\CompactFrameworkHelper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\CurrentTimeGetter.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\DictionaryBase.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\EnvironmentHelper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\ExtensionUtils.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\FactoryHelper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\FileInfoHelper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\FilterDictionary.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\FormHelper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\HttpUtility.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\InternalLogger.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\LayoutRendererDictionary.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\LogEventInfoBuffer.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\LoggerConfiguration.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\LoggerDictionary.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\MethodInfoDictionary.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\MultiFileWatcher.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\PlatformDetector.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\PropertyHelper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\PropertyInfoDictionary.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\StringCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\StringDictionary.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\TargetDictionary.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\TargetWithFilterChain.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\ThreadIDHelper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\TypeDictionary.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\TypeToPropertyInfoDictionaryAssociation.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\FileAppenders\BaseFileAppender.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\FileAppenders\CountingSingleProcessFileAppender.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\FileAppenders\ICreateFile.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\FileAppenders\IFileAppenderFactory.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\FileAppenders\MutexMultiProcessFileAppender.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\FileAppenders\RetryingMultiProcessFileAppender.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\FileAppenders\SingleProcessFileAppender.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\FileAppenders\UnixMultiProcessFileAppender.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\NetworkSenders\NetworkSender.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\NetworkSenders\TcpNetworkSender.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\NetworkSenders\UdpNetworkSender.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\Win32\Win32FileAttributes.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Internal\Win32\Win32FileHelper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\ASPNetApplication.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\ASPNetRequest.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\ASPNetSession.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\ASPNetSessionID.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\ASPNetUserAuthType.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\ASPNetUserIdentity.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\BaseDir.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\CallSite.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\Counter.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\Date.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\Environment.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\EventContext.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\Exception.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\FileContents.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\GC.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\GCD.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\Guid.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\Identity.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\Level.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\Literal.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\Log4JXmlEvent.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\LoggerName.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\LongDate.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\MachineName.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\MDC.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\Message.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\NDC.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\NewLine.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\NLogDir.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\PerformanceCounter.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\ProcessID.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\ProcessInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\ProcessName.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\ProcessTime.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\QPC.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\Rot13.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\ShortDate.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\SpecialFolder.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\StackTrace.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\TempDir.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\ThreadID.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\ThreadName.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "LayoutRenderers\Ticks.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Layouts\CsvColumn.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Layouts\CsvColumnCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Layouts\CsvLayout.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Layouts\CsvQuotingMode.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Layouts\LayoutWithHeaderAndFooter.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Layouts\Log4JXmlEventLayout.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <Folder RelPath = "Mono\" />
+ <File
+ RelPath = "Targets\ASPNetTrace.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Chainsaw.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Console.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Database.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\DatabaseParameterInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\DatabaseParameterInfoCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Debug.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Debugger.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\File.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\FormControl.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Mail.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Memory.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\MessageBox.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\MethodCall.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\MethodCallParameter.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\MethodCallParameterCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\MethodCallTargetBase.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Network.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\NLogViewer.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\NLogViewerParameterInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\NLogViewerParameterInfoCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Null.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\RichTextBox.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\RichTextBoxRowColoringRule.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\RichTextBoxRowColoringRuleCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\RichTextBoxWordColoringRule.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\RichTextBoxWordColoringRuleCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Trace.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\WebService.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Compound\CompoundTargetBase.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Compound\FallbackTarget.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Compound\RandomizeTarget.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Compound\RoundRobinTarget.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Compound\SplitTarget.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Wrappers\ASPNetBufferingTargetWrapper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Wrappers\AsyncTargetWrapper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Wrappers\AutoFlushTargetWrapper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Wrappers\BufferingTargetWrapper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Wrappers\FilteringRule.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Wrappers\FilteringRuleCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Wrappers\FilteringWrapper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Wrappers\ImpersonatingWrapper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Wrappers\PostFilteringWrapper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Wrappers\RepeatTargetWrapper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Wrappers\RetryTargetWrapper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Targets\Wrappers\WrapperTargetBase.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <Folder RelPath = "Unix\" />
+ <File
+ RelPath = "Web\NLogHttpModule.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\ASPHelper.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\LayoutRenderers\ASPApplication.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\LayoutRenderers\ASPRequest.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\LayoutRenderers\ASPSession.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\LayoutRenderers\Registry.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\LayoutRenderers\WindowsIdentity.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\Targets\ASPResponse.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\Targets\ColoredConsole.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\Targets\ConsoleOutputColor.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\Targets\ConsoleRowHighlightingRule.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\Targets\ConsoleRowHighlightingRuleCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\Targets\ConsoleWin32Api.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\Targets\ConsoleWordHighlightingRule.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\Targets\ConsoleWordHighlightingRuleCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\Targets\EventLog.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\Targets\MSMQ.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\Targets\OutputDebugString.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Win32\Targets\PerfCounterTarget.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ </Include>
+ </Files>
+ </CSHARP>
+</VisualStudioProject>
+
diff --git a/src/NLog/NLog.vs2005.csproj b/src/NLog/NLog.vs2005.csproj
new file mode 100644
index 0000000..6200986
--- /dev/null
+++ b/src/NLog/NLog.vs2005.csproj
@@ -0,0 +1,732 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectType>Local</ProjectType>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}</ProjectGuid>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ApplicationIcon>
+ </ApplicationIcon>
+ <AssemblyKeyContainerName>
+ </AssemblyKeyContainerName>
+ <AssemblyName>NLog</AssemblyName>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <DefaultClientScript>JScript</DefaultClientScript>
+ <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+ <DefaultTargetSchema>IE50</DefaultTargetSchema>
+ <DelaySign>false</DelaySign>
+ <OutputType>Library</OutputType>
+ <RootNamespace>NLog</RootNamespace>
+ <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+ <StartupObject>
+ </StartupObject>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <OutputPath>bin\Debug\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>DOTNET;DOTNET_2_0;NET_2_API</DefineConstants>
+ <DocumentationFile>NLog.xml</DocumentationFile>
+ <DebugSymbols>true</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>1699</NoWarn>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+ <WarningLevel>4</WarningLevel>
+ <DebugType>full</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <OutputPath>bin\Release\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>DOTNET;DOTNET_2_0;NET_2_API</DefineConstants>
+ <DocumentationFile>NLog.xml</DocumentationFile>
+ <DebugSymbols>false</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>1699</NoWarn>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+ <WarningLevel>4</WarningLevel>
+ <DebugType>none</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System">
+ <Name>System</Name>
+ </Reference>
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data">
+ <Name>system.data</Name>
+ </Reference>
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Messaging">
+ <Name>System.Messaging</Name>
+ </Reference>
+ <Reference Include="System.Web">
+ <Name>system.web</Name>
+ </Reference>
+ <Reference Include="System.Web.Services">
+ <Name>system.web.services</Name>
+ </Reference>
+ <Reference Include="System.Windows.Forms">
+ <Name>system.windows.forms</Name>
+ </Reference>
+ <Reference Include="System.Xml">
+ <Name>System.XML</Name>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AssemblyInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="AssemblySign.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="ConditionMethodAttribute.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="ConditionMethodFactory.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="ConditionMethodsAttribute.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionAndExpression.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionExpression.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionExpressionCollection.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionLayoutExpression.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionLevelExpression.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionLiteralExpression.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionLoggerNameExpression.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionMessageExpression.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionMethodExpression.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionMethods.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionNotExpression.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionOrExpression.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionParseException.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionParser.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionRelationalExpression.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionRelationalOperator.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionTokenizer.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Conditions\ConditionTokenType.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\AcceptsConditionAttribute.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\AcceptsLayoutAttribute.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\ArrayParameterAttribute.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\ConfigSectionHandler.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\DefaultParameterAttribute.cs" />
+ <Compile Include="Config\LoggingConfiguration.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\LoggingRule.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\LoggingRuleCollection.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\NLogConfigurationException.cs" />
+ <Compile Include="Config\NotSupportedRuntimeAttribute.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\RequiredParameterAttribute.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\RuntimeFramework.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\RuntimeOS.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\SimpleConfigurator.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\SupportedRuntimeAttribute.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\SupportedRuntimeAttributeBase.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Config\XmlLoggingConfiguration.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="AssemblyBuildInfo.cs" />
+ <Compile Include="LayoutParser.cs" />
+ <Compile Include="LayoutRenderers\Rot13.cs" />
+ <Compile Include="LayoutRenderers\FileContents.cs" />
+ <Compile Include="TargetWithLayoutHeaderAndFooter.cs" />
+ <Compile Include="Layouts\LayoutWithHeaderAndFooter.cs" />
+ <Compile Include="Internal\CurrentTimeGetter.cs" />
+ <Compile Include="LayoutFactory.cs" />
+ <Compile Include="LayoutAttribute.cs" />
+ <Compile Include="Filter.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FilterAttribute.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FilterCollection.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FilterFactory.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FilterResult.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Filters\ConditionBasedFilter.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Filters\LayoutBasedFilter.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Filters\WhenContains.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Filters\WhenEqual.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Filters\WhenNotContains.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Filters\WhenNotEqual.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="GDC.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="ILayout.cs" />
+ <Compile Include="Internal\CompactFrameworkHelper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\FileInfoHelper.cs" />
+ <Compile Include="Internal\FormHelper.cs" />
+ <Compile Include="Internal\Win32\Win32FileAttributes.cs" />
+ <Compile Include="Internal\Win32\Win32FileHelper.cs" />
+ <Compile Include="Internal\DictionaryBase.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\EnvironmentHelper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\ExtensionUtils.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\FactoryHelper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\FileAppenders\CountingSingleProcessFileAppender.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\FileAppenders\BaseFileAppender.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\FileAppenders\IFileAppenderFactory.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\FileAppenders\ICreateFile.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\FileAppenders\MutexMultiProcessFileAppender.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\FileAppenders\RetryingMultiProcessFileAppender.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\FileAppenders\SingleProcessFileAppender.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\FileAppenders\UnixMultiProcessFileAppender.cs" />
+ <Compile Include="Internal\FilterDictionary.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\HttpUtility.cs" />
+ <Compile Include="Internal\InternalLogger.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\LayoutRendererDictionary.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\LogEventInfoBuffer.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\LoggerConfiguration.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\LoggerDictionary.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\MethodInfoDictionary.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\MultiFileWatcher.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\NetworkSenders\NetworkSender.cs" />
+ <Compile Include="Internal\NetworkSenders\TcpNetworkSender.cs" />
+ <Compile Include="Internal\NetworkSenders\UdpNetworkSender.cs" />
+ <Compile Include="Internal\PlatformDetector.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\PropertyHelper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\PropertyInfoDictionary.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\StringCollection.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\StringDictionary.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\TargetDictionary.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\TargetWithFilterChain.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\ThreadIDHelper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\TypeDictionary.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Internal\TypeToPropertyInfoDictionaryAssociation.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Layout.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutCollection.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderer.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRendererAttribute.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRendererCollection.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRendererFactory.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ASPNetApplication.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ASPNetRequest.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ASPNetSession.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ASPNetSessionID.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ASPNetUserAuthType.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ASPNetUserIdentity.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\BaseDir.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\CallSite.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\GC.cs" />
+ <Compile Include="LayoutRenderers\ProcessInfo.cs" />
+ <Compile Include="LayoutRenderers\SpecialFolder.cs" />
+ <Compile Include="LayoutRenderers\TempDir.cs" />
+ <Compile Include="LayoutRenderers\QPC.cs" />
+ <Compile Include="LayoutRenderers\Counter.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\Date.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\Environment.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\Exception.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\GCD.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\Guid.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\Identity.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\Level.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\Literal.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\Log4JXmlEvent.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\LoggerName.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\LongDate.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\MachineName.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\MDC.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\Message.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\NDC.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\NewLine.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\NLogDir.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\PerformanceCounter.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ProcessID.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ProcessName.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ProcessTime.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ShortDate.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\StackTrace.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ThreadID.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ThreadName.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\Ticks.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Layouts\CsvLayout.cs" />
+ <Compile Include="Layouts\Log4JXmlEventLayout.cs" />
+ <Compile Include="LogEventInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Logger.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LoggerImpl.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LogLevel.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LogManager.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="MDC.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="NDC.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Target.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="TargetAttribute.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="TargetCollection.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="TargetFactory.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\ASPNetTrace.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Chainsaw.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Compound\CompoundTargetBase.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Compound\FallbackTarget.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Compound\RandomizeTarget.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Compound\RoundRobinTarget.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Compound\SplitTarget.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Console.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Layouts\CsvQuotingMode.cs" />
+ <Compile Include="Layouts\CsvColumnCollection.cs" />
+ <Compile Include="Layouts\CsvColumn.cs" />
+ <Compile Include="Targets\Database.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\DatabaseParameterInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\DatabaseParameterInfoCollection.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Debug.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Debugger.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\File.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\FormControl.cs" />
+ <Compile Include="Targets\Mail.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Memory.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\MessageBox.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\MethodCall.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\MethodCallParameter.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\MethodCallParameterCollection.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\MethodCallTargetBase.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Network.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\NLogViewer.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\NLogViewerParameterInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\NLogViewerParameterInfoCollection.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Null.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\RichTextBox.cs" />
+ <Compile Include="Targets\RichTextBoxRowColoringRule.cs" />
+ <Compile Include="Targets\RichTextBoxRowColoringRuleCollection.cs" />
+ <Compile Include="Targets\RichTextBoxWordColoringRule.cs" />
+ <Compile Include="Targets\RichTextBoxWordColoringRuleCollection.cs" />
+ <Compile Include="Targets\Trace.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\WebService.cs">
+ </Compile>
+ <Compile Include="Targets\Wrappers\ASPNetBufferingTargetWrapper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Wrappers\AsyncTargetWrapper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Wrappers\AutoFlushTargetWrapper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Wrappers\BufferingTargetWrapper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Wrappers\ImpersonatingWrapper.cs" />
+ <Compile Include="Targets\Wrappers\FilteringRule.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Wrappers\FilteringRuleCollection.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Wrappers\FilteringWrapper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Wrappers\PostFilteringWrapper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Wrappers\RepeatTargetWrapper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Wrappers\RetryTargetWrapper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\Wrappers\WrapperTargetBase.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="TargetWithLayout.cs" />
+ <Compile Include="Web\NLogHttpModule.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\ASPHelper.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\LayoutRenderers\ASPApplication.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\LayoutRenderers\ASPRequest.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\LayoutRenderers\ASPSession.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\LayoutRenderers\Registry.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\LayoutRenderers\WindowsIdentity.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\Targets\ASPResponse.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\Targets\ColoredConsole.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\Targets\ConsoleOutputColor.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\Targets\ConsoleRowHighlightingRule.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\Targets\ConsoleRowHighlightingRuleCollection.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\Targets\ConsoleWin32Api.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\Targets\ConsoleWordHighlightingRule.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\Targets\ConsoleWordHighlightingRuleCollection.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\Targets\EventLog.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\Targets\MSMQ.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\Targets\OutputDebugString.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Win32\Targets\PerfCounterTarget.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LogFactory.cs" />
+ <Compile Include="ILayoutWithHeaderAndFooter.cs" />
+ <Compile Include="LayoutRenderers\EventContext.cs" />
+ </ItemGroup>
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup>
+ <Folder Include="DotNet\" />
+ <Folder Include="Mono\" />
+ <Folder Include="Unix\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>"$(ProjectDir)..\..\tools\UpdateBuildNumber.exe" "$(ProjectDir)..\..\NLog.version" "$(ProjectDir)AssemblyBuildInfo.cs" "$(ProjectDir)..\..\build\NLog.buildversion"</PreBuildEvent>
+ <PostBuildEvent>
+ </PostBuildEvent>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/src/NLog/Target.cs b/src/NLog/Target.cs
new file mode 100644
index 0000000..83c2ee0
--- /dev/null
+++ b/src/NLog/Target.cs
@@ -0,0 +1,256 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+
+using NLog.Config;
+
+namespace NLog
+{
+ /// <summary>
+ /// Represents logging target.
+ /// </summary>
+ public abstract class Target
+ {
+ /// <summary>
+ /// Creates a new instance of the logging target and initializes
+ /// default layout.
+ /// </summary>
+ /// <remarks>
+ /// The default value of the layout is: <code>${longdate}|${level:uppercase=true}|${logger}|${message}</code>
+ /// </remarks>
+ protected Target()
+ {
+ }
+
+ /// <summary>
+ /// Gets the collection of <see cref="Layout"/> objects that are used
+ /// by this target.
+ /// </summary>
+ /// <returns>A <see cref="LayoutCollection"/> object which is a typed collection
+ /// of <see cref="Layout"/> objects. The collection is cached and accumulated
+ /// by calling <see cref="PopulateLayouts"/>.</returns>
+ public LayoutCollection GetLayouts()
+ {
+ LayoutCollection lc = _allLayouts;
+ if (lc == null)
+ {
+ lock (this)
+ {
+ lc = _allLayouts;
+ if (lc == null)
+ {
+ lc = new LayoutCollection();
+ PopulateLayouts(lc);
+ _allLayouts = lc;
+ return lc;
+ }
+ else
+ {
+ return lc;
+ }
+ }
+ }
+ else
+ {
+ return lc;
+ }
+ }
+
+ /// <summary>
+ /// Invalidates the collection of layouts cached by <see cref="GetLayouts"/>.
+ /// </summary>
+ protected void InvalidateLayouts()
+ {
+ _allLayouts = null;
+ }
+
+ private LayoutCollection _allLayouts = null;
+ private int _needsStackTrace = -1;
+ private string _name;
+
+ /// <summary>
+ /// The name of the target.
+ /// </summary>
+ [RequiredParameter]
+ public string Name
+ {
+ get { return _name; }
+ set { _name = value; }
+ }
+
+ /// <summary>
+ /// Writes logging event to the log target. Must be overridden in inheriting
+ /// classes.
+ /// </summary>
+ /// <param name="logEvent">Logging event to be written out.</param>
+ protected internal abstract void Write(LogEventInfo logEvent);
+
+ /// <summary>
+ /// Writes an array of logging events to the log target. By default it iterates on all
+ /// events and passes them to "Append" method. Inheriting classes can use this method to
+ /// optimize batch writes.
+ /// </summary>
+ /// <param name="logEvents">Logging events to be written out.</param>
+ protected internal virtual void Write(LogEventInfo[] logEvents)
+ {
+ for (int i = 0; i < logEvents.Length; ++i)
+ {
+ Write(logEvents[i]);
+ }
+ }
+
+ /// <summary>
+ /// Determines whether stack trace information should be gathered
+ /// during log event processing. By default it calls <see cref="NLog.Layout.NeedsStackTrace" /> on
+ /// the result of <see cref="GetLayouts()"/>.
+ /// </summary>
+ /// <returns>0 - don't include stack trace<br/>1 - include stack trace without source file information<br/>2 - include full stack trace</returns>
+ protected internal virtual int NeedsStackTrace()
+ {
+ int nst = _needsStackTrace;
+
+ if (nst == -1)
+ {
+ lock (this)
+ {
+ nst = _needsStackTrace;
+ if (nst == -1)
+ {
+ int max = 0;
+ LayoutCollection layouts = GetLayouts();
+
+ for (int i = 0; i < layouts.Count; ++i)
+ {
+ max = Math.Max(max, layouts[i].NeedsStackTrace());
+ if (max == 2)
+ break;
+ }
+ nst = max;
+ _needsStackTrace = nst;
+ }
+ }
+ }
+
+ return nst;
+ }
+
+ /// <summary>
+ /// Returns the text representation of the object. Used for diagnostics.
+ /// </summary>
+ /// <returns>A string that describes the target.</returns>
+ public override string ToString()
+ {
+ return ((this.Name != null) ? this.Name : "unnamed") + ":" + this.GetType().Name;
+ }
+
+ /// <summary>
+ /// Flush any pending log messages (in case of asynchronous targets).
+ /// </summary>
+ public void Flush()
+ {
+ Flush(TimeSpan.MaxValue);
+ }
+
+ /// <summary>
+ /// Flush any pending log messages (in case of asynchronous targets).
+ /// </summary>
+ /// <param name="timeout">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
+ public virtual void Flush(TimeSpan timeout)
+ {
+ // do nothing
+ }
+
+ /// <summary>
+ /// Flush any pending log messages (in case of asynchronous targets).
+ /// </summary>
+ /// <param name="timeoutMilliseconds">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
+ public void Flush(int timeoutMilliseconds)
+ {
+ Flush(TimeSpan.FromMilliseconds(timeoutMilliseconds));
+ }
+
+ /// <summary>
+ /// Closes the target and releases any unmanaged resources.
+ /// </summary>
+ protected internal virtual void Close()
+ {
+ foreach (ILayout l in GetLayouts())
+ {
+ l.Close();
+ }
+ }
+
+ /// <summary>
+ /// Calls the <see cref="NLog.Layout.Precalculate"/> on each volatile layout
+ /// used by this target.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ /// <remarks>
+ /// A layout is volatile if it contains at least one <see cref="Layout"/> for
+ /// which <see cref="LayoutRenderer.IsVolatile"/> returns true.
+ /// </remarks>
+ public void PrecalculateVolatileLayouts(LogEventInfo logEvent)
+ {
+ LayoutCollection layouts = GetLayouts();
+
+ for (int i = 0; i < layouts.Count; ++i)
+ {
+ if (layouts[i].IsVolatile())
+ layouts[i].Precalculate(logEvent);
+ }
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public virtual void PopulateLayouts(LayoutCollection layouts)
+ {
+ }
+
+ /// <summary>
+ /// Initializes the target. Can be used by inheriting classes
+ /// to initialize logging.
+ /// </summary>
+ public virtual void Initialize()
+ {
+ foreach (ILayout l in GetLayouts())
+ {
+ l.Initialize();
+ }
+ }
+ }
+}
diff --git a/src/NLog/TargetAttribute.cs b/src/NLog/TargetAttribute.cs
new file mode 100644
index 0000000..b2f9769
--- /dev/null
+++ b/src/NLog/TargetAttribute.cs
@@ -0,0 +1,93 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+namespace NLog
+{
+ /// <summary>
+ /// Marks class as a logging target and assigns a name to it.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class)]
+ public sealed class TargetAttribute: Attribute
+ {
+ private string _name;
+ private bool _ignoresLayout = false;
+ private bool _isCompound = false;
+ private bool _isWrapper = false;
+
+ /// <summary>
+ /// Creates a new instance of the TargetAttribute class and sets the name.
+ /// </summary>
+ /// <param name="name"></param>
+ public TargetAttribute(string name)
+ {
+ _name = name;
+ }
+
+ /// <summary>
+ /// The name of the logging target.
+ /// </summary>
+ public string Name
+ {
+ get { return _name; }
+ }
+
+ /// <summary>
+ /// Determines whether the target ignores layout specification.
+ /// </summary>
+ public bool IgnoresLayout
+ {
+ get { return _ignoresLayout; }
+ set { _ignoresLayout = value; }
+ }
+
+ /// <summary>
+ /// Marks the target as 'wrapper' target (used to generate the target summary documentation page);
+ /// </summary>
+ public bool IsWrapper
+ {
+ get { return _isWrapper; }
+ set { _isWrapper = value; }
+ }
+
+ /// <summary>
+ /// Marks the target as 'compound' target (used to generate the target summary documentation page);
+ /// </summary>
+ public bool IsCompound
+ {
+ get { return _isCompound; }
+ set { _isCompound = value; }
+ }
+ }
+}
diff --git a/src/NLog/TargetCollection.cs b/src/NLog/TargetCollection.cs
new file mode 100644
index 0000000..7bf1b75
--- /dev/null
+++ b/src/NLog/TargetCollection.cs
@@ -0,0 +1,240 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace NLog
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A collection of elements of type Target
+ /// </summary>
+ public class TargetCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the TargetCollection class.
+ /// </summary>
+ public TargetCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the TargetCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new TargetCollection.
+ /// </param>
+ public TargetCollection(Target[]items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the TargetCollection class, containing elements
+ /// copied from another instance of TargetCollection
+ /// </summary>
+ /// <param name="items">
+ /// The TargetCollection whose elements are to be added to the new TargetCollection.
+ /// </param>
+ public TargetCollection(TargetCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this TargetCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this TargetCollection.
+ /// </param>
+ public virtual void AddRange(Target[]items)
+ {
+ foreach (Target item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another TargetCollection to the end of this TargetCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The TargetCollection whose elements are to be added to the end of this TargetCollection.
+ /// </param>
+ public virtual void AddRange(TargetCollection items)
+ {
+ foreach (Target item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type Target to the end of this TargetCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The Target to be added to the end of this TargetCollection.
+ /// </param>
+ public virtual void Add(Target value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic Target value is in this TargetCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The Target value to locate in this TargetCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this TargetCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(Target value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this TargetCollection
+ /// </summary>
+ /// <param name="value">
+ /// The Target value to locate in the TargetCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(Target value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the TargetCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the Target is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The Target to insert.
+ /// </param>
+ public virtual void Insert(int index, Target value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the Target at the given index in this TargetCollection.
+ /// </summary>
+ public virtual Target this[int index]
+ {
+ get { return (Target)this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific Target from this TargetCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The Target value to remove from this TargetCollection.
+ /// </param>
+ public virtual void Remove(Target value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by TargetCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(TargetCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public Target Current
+ {
+ get { return (Target)(this.wrapped.Current); }
+ }
+
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (Target)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this TargetCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual TargetCollection.Enumerator GetEnumerator()
+ {
+ return new TargetCollection.Enumerator(this);
+ }
+ }
+}
diff --git a/src/NLog/TargetFactory.cs b/src/NLog/TargetFactory.cs
new file mode 100644
index 0000000..6f2d8e7
--- /dev/null
+++ b/src/NLog/TargetFactory.cs
@@ -0,0 +1,161 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Reflection;
+using System.Globalization;
+
+using NLog.Internal;
+
+namespace NLog
+{
+ /// <summary>
+ /// A factory of logging targets. Creates new targets based on their names.
+ /// </summary>
+ public sealed class TargetFactory
+ {
+ private static TypeDictionary _targets = new TypeDictionary();
+
+ static TargetFactory()
+ {
+ foreach (Assembly a in ExtensionUtils.GetExtensionAssemblies())
+ {
+ AddTargetsFromAssembly(a, "");
+ }
+ }
+
+ private TargetFactory(){}
+
+ /// <summary>
+ /// Removes all target information from the factory.
+ /// </summary>
+ public static void Clear()
+ {
+ _targets.Clear();
+ }
+
+ /// <summary>
+ /// Removes all targets and reloads them from NLog assembly and default extension assemblies.
+ /// </summary>
+ public static void Reset()
+ {
+ Clear();
+ AddDefaultTargets();
+ }
+
+ /// <summary>
+ /// Scans the specified assembly for types marked with <see cref="TargetAttribute" /> and adds
+ /// them to the factory. Optionally it prepends the specified text to the target names to avoid
+ /// naming collisions.
+ /// </summary>
+ /// <param name="theAssembly">The assembly to be scanned for targets.</param>
+ /// <param name="prefix">The prefix to be prepended to target names.</param>
+ public static void AddTargetsFromAssembly(Assembly theAssembly, string prefix)
+ {
+ try
+ {
+ InternalLogger.Debug("AddTargetsFromAssembly('{0}')", theAssembly.FullName);
+ foreach (Type t in theAssembly.GetTypes())
+ {
+ TargetAttribute[]attributes = (TargetAttribute[])t.GetCustomAttributes(typeof(TargetAttribute), false);
+ if (attributes != null)
+ {
+ foreach (TargetAttribute attr in attributes)
+ {
+ if (PlatformDetector.IsSupportedOnCurrentRuntime(t))
+ {
+ AddTarget(prefix + attr.Name, t);
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Failed to add targets from '" + theAssembly.FullName + "': {0}", ex);
+ }
+ }
+
+ /// <summary>
+ /// Adds default targets from the NLog.dll assembly.
+ /// </summary>
+ private static void AddDefaultTargets()
+ {
+ AddTargetsFromAssembly(typeof(TargetFactory).Assembly, String.Empty);
+ }
+
+ /// <summary>
+ /// Registers the specified target type to the factory under a specified name.
+ /// </summary>
+ /// <param name="targetName">The name of the target (e.g. <code>File</code> or <code>Console</code>)</param>
+ /// <param name="targetType">The type of the new target</param>
+ /// <remarks>
+ /// The name specified in the targetName parameter can then be used
+ /// to create target.
+ /// </remarks>
+ public static void AddTarget(string targetName, Type targetType)
+ {
+ string hashKey = targetName.ToLower(CultureInfo.InvariantCulture);
+
+ InternalLogger.Trace("Registering target {0} for type '{1}')", targetName, targetType);
+ _targets[hashKey] = targetType;
+ }
+
+ /// <summary>
+ /// Creates the target object based on its target name.
+ /// </summary>
+ /// <param name="name">The name of the target (e.g. <code>File</code> or <code>Console</code>)</param>
+ /// <returns>A new instance of the Target object.</returns>
+ public static Target CreateTarget(string name)
+ {
+ Type t = _targets[name.ToLower(CultureInfo.InvariantCulture)];
+ if (t != null)
+ {
+ Target la = FactoryHelper.CreateInstance(t) as Target;
+ if (la != null)
+ return la;
+ }
+ throw new ArgumentException("Target " + name + " not found.");
+ }
+
+ /// <summary>
+ /// Collection of target types added to the factory.
+ /// </summary>
+ public static ICollection TargetTypes
+ {
+ get { return _targets.Values; }
+ }
+ }
+}
diff --git a/src/NLog/TargetWithLayout.cs b/src/NLog/TargetWithLayout.cs
new file mode 100644
index 0000000..a2bdd76
--- /dev/null
+++ b/src/NLog/TargetWithLayout.cs
@@ -0,0 +1,96 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+
+using NLog.Config;
+
+namespace NLog
+{
+ /// <summary>
+ /// Represents target that supports string formatting using layouts.
+ /// </summary>
+ public abstract class TargetWithLayout : Target
+ {
+ private ILayout _compiledlayout;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="TargetWithLayout" />
+ /// </summary>
+ protected TargetWithLayout()
+ {
+ Layout = "${longdate}|${level:uppercase=true}|${logger}|${message}";
+ }
+
+ /// <summary>
+ /// The text to be rendered.
+ /// </summary>
+ [RequiredParameter]
+ [AcceptsLayout]
+ [System.ComponentModel.DefaultValue("${longdate}|${level:uppercase=true}|${logger}|${message}")]
+ public virtual string Layout
+ {
+ get { return Convert.ToString(_compiledlayout); }
+ set { _compiledlayout = new Layout(value); }
+ }
+
+ /// <summary>
+ /// The compiled layout, can be an instance of <see cref="Layout"/> or other layout type.
+ /// </summary>
+ public virtual ILayout CompiledLayout
+ {
+ get { return _compiledlayout; }
+ set { _compiledlayout = value; }
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ if (this.CompiledLayout != null)
+ this.CompiledLayout.PopulateLayouts(layouts);
+ }
+
+ /// <summary>
+ /// Initializes the target.
+ /// </summary>
+ public override void Initialize()
+ {
+ this.CompiledLayout.Initialize();
+ }
+ }
+}
diff --git a/src/NLog/TargetWithLayoutHeaderAndFooter.cs b/src/NLog/TargetWithLayoutHeaderAndFooter.cs
new file mode 100644
index 0000000..6ff7605
--- /dev/null
+++ b/src/NLog/TargetWithLayoutHeaderAndFooter.cs
@@ -0,0 +1,167 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+
+using NLog.Config;
+using NLog.Layouts;
+
+namespace NLog
+{
+ /// <summary>
+ /// Represents target that supports string formatting using layouts.
+ /// </summary>
+ public abstract class TargetWithLayoutHeaderAndFooter : TargetWithLayout
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="TargetWithLayout" />
+ /// </summary>
+ protected TargetWithLayoutHeaderAndFooter()
+ {
+ LayoutWithHeaderAndFooter h = new LayoutWithHeaderAndFooter();
+ h.Layout = new Layout("${longdate}|${level:uppercase=true}|${logger}|${message}");
+ CompiledLayout = h;
+ }
+
+ /// <summary>
+ /// The text to be rendered.
+ /// </summary>
+ [RequiredParameter]
+ [AcceptsLayout]
+ [System.ComponentModel.DefaultValue("${longdate}|${level:uppercase=true}|${logger}|${message}")]
+ public override string Layout
+ {
+ get { return Convert.ToString(CompiledLayoutWithHeaderAndFooter.Layout); }
+ set
+ {
+ if (CompiledLayoutWithHeaderAndFooter != null)
+ CompiledLayoutWithHeaderAndFooter.Layout = new Layout(value);
+ }
+ }
+
+ /// <summary>
+ /// Header
+ /// </summary>
+ [AcceptsLayout]
+ public string Header
+ {
+ get { return Convert.ToString(CompiledHeader); }
+ set { CompiledHeader = new Layout(value); }
+ }
+
+ /// <summary>
+ /// Footer
+ /// </summary>
+ [AcceptsLayout]
+ public string Footer
+ {
+ get { return Convert.ToString(CompiledFooter); }
+ set { CompiledFooter = new Layout(value); }
+ }
+
+
+ /// <summary>
+ /// Compiled header.
+ /// </summary>
+ /// <value>The compiled header.</value>
+ /// <remarks>
+ /// The header can be of any layout type.
+ /// </remarks>
+ public ILayout CompiledHeader
+ {
+ get
+ {
+ ILayoutWithHeaderAndFooter h = CompiledLayoutWithHeaderAndFooter;
+ if (h != null)
+ return h.Header;
+ return null;
+ }
+ set
+ {
+ ILayoutWithHeaderAndFooter h = CompiledLayoutWithHeaderAndFooter;
+ h.Header = value;
+ }
+ }
+
+ /// <summary>
+ /// Compiled footer.
+ /// </summary>
+ /// <value>The compiled footer.</value>
+ /// <remarks>
+ /// The header can be of any layout type.
+ /// </remarks>
+ public ILayout CompiledFooter
+ {
+ get
+ {
+ ILayoutWithHeaderAndFooter h = CompiledLayoutWithHeaderAndFooter;
+ if (h != null)
+ return h.Footer;
+ return null;
+ }
+ set
+ {
+ ILayoutWithHeaderAndFooter h = CompiledLayoutWithHeaderAndFooter;
+ h.Footer = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the compiled layout with header and footer.
+ /// </summary>
+ /// <value>The compiled layout with header and footer.</value>
+ public ILayoutWithHeaderAndFooter CompiledLayoutWithHeaderAndFooter
+ {
+ get { return base.CompiledLayout as ILayoutWithHeaderAndFooter; }
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ this.CompiledLayout.PopulateLayouts(layouts);
+ }
+
+ /// <summary>
+ /// Initializes the target.
+ /// </summary>
+ public override void Initialize()
+ {
+ this.CompiledLayout.Initialize();
+ }
+ }
+}
diff --git a/src/NLog/Targets/ASPNetTrace.cs b/src/NLog/Targets/ASPNetTrace.cs
new file mode 100644
index 0000000..3de86f6
--- /dev/null
+++ b/src/NLog/Targets/ASPNetTrace.cs
@@ -0,0 +1,108 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+using System;
+using System.Web;
+
+using NLog.Targets;
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Writes logging messages to the ASP.NET trace.
+ /// </summary>
+ /// <example>
+ /// <p>To set up the ASP.NET Trace target in the <a href="config.html">configuration file</a>, put
+ /// the following in <c>web.nlog</c> file in your web application directory.
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/ASPNetTrace/web.nlog" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To configure the target programmatically, put the following
+ /// piece of code in your <c>Application_OnStart()</c> handler in Global.asax.cs
+ /// or some other place that gets executed at the very beginning of your code:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/ASPNetTrace/Global.asax.cs" />
+ /// <p>
+ /// Fully working C# project can be found in the <c>Examples/Targets/Configuration API/ASPNetTrace</c>
+ /// directory along with usage instructions.
+ /// </p>
+ /// Resulting log entries can be viewed by navigating to http://server/path/Trace.axd.
+ /// <br/>
+ /// <b>HTTP Request List:</b><br/>
+ /// <img src="examples/targets/Screenshots/ASPNetTrace/ASPNetTraceOutput1.gif" />
+ /// <p/>
+ /// <b>HTTP Request Details:</b>
+ /// <br/>
+ /// <img src="examples/targets/Screenshots/ASPNetTrace/ASPNetTraceOutput2.gif" />
+ /// <p/>
+ /// </example>
+ [Target("ASPNetTrace")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class ASPNetTraceTarget: TargetWithLayout
+ {
+ /// <summary>
+ /// Writes the specified logging event to the ASP.NET Trace facility. Log entries
+ /// can then be viewed by navigating to http://server/path/Trace.axd
+ /// If the log level is greater than or equal to <see cref="LogLevel.Warn"/> it uses the
+ /// <see cref="System.Web.TraceContext.Warn(String,String)"/> method, otherwise it uses
+ /// <see cref="System.Web.TraceContext.Write(String,String)" /> method.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ HttpContext context = HttpContext.Current;
+
+ if (context == null)
+ {
+ return ;
+ }
+
+ if (logEvent.Level >= LogLevel.Warn)
+ {
+ context.Trace.Warn(logEvent.LoggerName, CompiledLayout.GetFormattedMessage(logEvent));
+ }
+ else
+ {
+ context.Trace.Write(logEvent.LoggerName, CompiledLayout.GetFormattedMessage(logEvent));
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Targets/Chainsaw.cs b/src/NLog/Targets/Chainsaw.cs
new file mode 100644
index 0000000..1a05a8b
--- /dev/null
+++ b/src/NLog/Targets/Chainsaw.cs
@@ -0,0 +1,85 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Sends logging messages to the remote instance of Chainsaw application from log4j.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/Chainsaw/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/Chainsaw/Simple/Example.cs" />
+ /// <p>
+ /// NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol
+ /// or you'll get TCP timeouts and your application will crawl.
+ /// Either switch to UDP transport or use <a href="target.AsyncWrapper.html">AsyncWrapper</a> target
+ /// so that your application threads will not be blocked by the timing-out connection attempts.
+ /// </p>
+ /// </example>
+ [Target("Chainsaw", IgnoresLayout=true)]
+ public class ChainsawTarget: NLogViewerTarget
+ {
+ /// <summary>
+ /// Creates a new instance of the <see cref="ChainsawTarget"/>
+ /// and initializes default property values.
+ /// </summary>
+ public ChainsawTarget()
+ {
+ IncludeNLogData = false;
+ }
+ }
+}
diff --git a/src/NLog/Targets/Compound/CompoundTargetBase.cs b/src/NLog/Targets/Compound/CompoundTargetBase.cs
new file mode 100644
index 0000000..69766d1
--- /dev/null
+++ b/src/NLog/Targets/Compound/CompoundTargetBase.cs
@@ -0,0 +1,118 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+
+using NLog.Config;
+
+namespace NLog.Targets.Compound
+{
+ /// <summary>
+ /// A base class for targets which wrap other (multiple) targets
+ /// and provide various forms of target routing.
+ /// </summary>
+ public abstract class CompoundTargetBase: Target
+ {
+ private TargetCollection _targets = new TargetCollection();
+
+ /// <summary>
+ /// Creates a new instance of <see cref="CompoundTargetBase"/>.
+ /// </summary>
+ public CompoundTargetBase()
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="CompoundTargetBase"/> and
+ /// initializes the <see cref="Targets"/> collection to the provided
+ /// list of <see cref="Target"/> objects.
+ /// </summary>
+ public CompoundTargetBase(params Target[] targets)
+ {
+ _targets.AddRange(targets);
+ }
+
+ /// <summary>
+ /// A collection of targets managed by this compound target.
+ /// </summary>
+ public TargetCollection Targets
+ {
+ get { return _targets; }
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target and sub-targets.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ base.PopulateLayouts (layouts);
+ foreach (Target t in Targets)
+ {
+ t.PopulateLayouts(layouts);
+ }
+ }
+
+ /// <summary>
+ /// Initializes the target by initializing all sub-targets.
+ /// </summary>
+ public override void Initialize()
+ {
+ foreach (Target t in Targets)
+ {
+ t.Initialize();
+ }
+ }
+
+ /// <summary>
+ /// Closes the target by closing all sub-targets.
+ /// </summary>
+ protected internal override void Close()
+ {
+ base.Close ();
+ foreach (Target t in Targets)
+ {
+ t.Close();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/NLog/Targets/Compound/FallbackTarget.cs b/src/NLog/Targets/Compound/FallbackTarget.cs
new file mode 100644
index 0000000..2e4215d
--- /dev/null
+++ b/src/NLog/Targets/Compound/FallbackTarget.cs
@@ -0,0 +1,136 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+
+using NLog.Config;
+
+namespace NLog.Targets.Compound
+{
+ /// <summary>
+ /// A compound target that provides fallback-on-error functionality.
+ /// </summary>
+ /// <example>
+ /// <p>This example causes the messages to be written to server1,
+ /// and if it fails, messages go to server2.</p>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/FallbackGroup/NLog.config" />
+ /// <p>
+ /// The above examples assume just one target and a single rule. See below for
+ /// a programmatic configuration that's equivalent to the above config file:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/FallbackGroup/Simple/Example.cs" />
+ /// </example>
+ [Target("FallbackGroup", IgnoresLayout = true, IsCompound = true)]
+ public class FallbackTarget: CompoundTargetBase
+ {
+ private int _currentTarget = 0;
+ private bool _returnToFirstOnSuccess = false;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="FallbackTarget"/>.
+ /// </summary>
+ public FallbackTarget()
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="FallbackTarget"/> and sets
+ /// the targets to be used.
+ /// </summary>
+ public FallbackTarget(params Target[] targets) : base(targets)
+ {
+ }
+
+ /// <summary>
+ /// Whether to return to the first target after any successful write.
+ /// </summary>
+ public bool ReturnToFirstOnSuccess
+ {
+ get { return _returnToFirstOnSuccess; }
+ set { _returnToFirstOnSuccess = value; }
+ }
+
+ /// <summary>
+ /// Forwards the log event to the sub-targets until one of them succeeds.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ /// <remarks>
+ /// The method remembers the last-known-successful target
+ /// and starts the iteration from it.
+ /// If <see cref="ReturnToFirstOnSuccess"/> is set, the method
+ /// resets the target to the first target
+ /// stored in <see cref="Targets"/>.
+ /// </remarks>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ lock (this)
+ {
+ for (int i = 0; i < Targets.Count; ++i)
+ {
+ try
+ {
+ Targets[_currentTarget].Write(logEvent);
+ if (_currentTarget != 0)
+ {
+ if (ReturnToFirstOnSuccess)
+ {
+ InternalLogger.Debug("Fallback: target '{0}' succeeded. Returning to the first one.", Targets[_currentTarget]);
+ _currentTarget = 0;
+ }
+ }
+ return;
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Warn("Fallback: target '{0}' failed. Proceeding to the next one. Error was: {1}", Targets[_currentTarget], ex);
+ // error while writing, try another one
+ _currentTarget = (_currentTarget + 1) % Targets.Count;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/NLog/Targets/Compound/RandomizeTarget.cs b/src/NLog/Targets/Compound/RandomizeTarget.cs
new file mode 100644
index 0000000..d8fa928
--- /dev/null
+++ b/src/NLog/Targets/Compound/RandomizeTarget.cs
@@ -0,0 +1,99 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+
+using NLog.Config;
+
+namespace NLog.Targets.Compound
+{
+ /// <summary>
+ /// A compound target writes to a randomly-chosen target among the sub-targets.
+ /// </summary>
+ /// <example>
+ /// <p>This example causes the messages to be written to either file1.txt or file2.txt
+ /// chosen randomly on a per-message basis.
+ /// </p>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/RandomizeGroup/NLog.config" />
+ /// <p>
+ /// The above examples assume just one target and a single rule. See below for
+ /// a programmatic configuration that's equivalent to the above config file:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/RandomizeGroup/Simple/Example.cs" />
+ /// </example>
+ [Target("RandomizeGroup", IgnoresLayout = true, IsCompound = true)]
+ public class RandomizeTarget: CompoundTargetBase
+ {
+ private static Random _random = new Random();
+
+ /// <summary>
+ /// Creates an instance of <see cref="RandomizeTarget"/>.
+ /// </summary>
+ public RandomizeTarget()
+ {
+ }
+
+ /// <summary>
+ /// Creates an instance of <see cref="RandomizeTarget"/> and
+ /// initializes the <see cref="Targets"/> collection with the
+ /// specified list of <see cref="Target"/> objects.
+ /// </summary>
+ public RandomizeTarget(params Target[] targets) : base(targets)
+ {
+ }
+
+ /// <summary>
+ /// Forwards the log event to one of the sub-targets.
+ /// The sub-target is randomly chosen.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ int pos = _random.Next(Targets.Count);
+ Targets[pos].Write(logEvent);
+ }
+ }
+}
diff --git a/src/NLog/Targets/Compound/RoundRobinTarget.cs b/src/NLog/Targets/Compound/RoundRobinTarget.cs
new file mode 100644
index 0000000..29cc9b7
--- /dev/null
+++ b/src/NLog/Targets/Compound/RoundRobinTarget.cs
@@ -0,0 +1,108 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+using NLog.Config;
+
+namespace NLog.Targets.Compound
+{
+ /// <summary>
+ /// A compound target that forwards writes to the sub-targets in a
+ /// round-robin fashion.
+ /// </summary>
+ /// <example>
+ /// <p>This example causes the messages to be written to either file1.txt or file2.txt.
+ /// Each odd message is written to file2.txt, each even message goes to file1.txt.
+ /// </p>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/RoundRobinGroup/NLog.config" />
+ /// <p>
+ /// The above examples assume just one target and a single rule. See below for
+ /// a programmatic configuration that's equivalent to the above config file:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/RoundRobinGroup/Simple/Example.cs" />
+ /// </example>
+ [Target("RoundRobinGroup", IgnoresLayout = true, IsCompound = true)]
+ public class RoundRobinTarget: CompoundTargetBase
+ {
+ private int _currentTarget = 0;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="RoundRobinTarget"/>.
+ /// </summary>
+ public RoundRobinTarget()
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="RoundRobinTarget"/> and initializes
+ /// the <see cref="Targets"/> collection to the provided
+ /// array of <see cref="Target"/> objects.
+ /// </summary>
+ public RoundRobinTarget(params Target[] targets) : base(targets)
+ {
+ }
+
+ /// <summary>
+ /// Forwards the write to one of the targets from
+ /// the <see cref="Targets"/> collection.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ /// <remarks>
+ /// The writes are routed in a round-robin fashion.
+ /// The first log event goes to the first target, the second
+ /// one goes to the second target and so on looping to the
+ /// first target when there are no more targets available.
+ /// In general request N goes to Targets[N % Targets.Count].
+ /// </remarks>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ int currentTarget = Interlocked.Increment(ref _currentTarget);
+ Targets[currentTarget % Targets.Count].Write(logEvent);
+ }
+ }
+}
diff --git a/src/NLog/Targets/Compound/SplitTarget.cs b/src/NLog/Targets/Compound/SplitTarget.cs
new file mode 100644
index 0000000..2ae2cf1
--- /dev/null
+++ b/src/NLog/Targets/Compound/SplitTarget.cs
@@ -0,0 +1,98 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+
+using NLog.Config;
+
+namespace NLog.Targets.Compound
+{
+ /// <summary>
+ /// A compound target that writes logging events to all attached
+ /// sub-targets.
+ /// </summary>
+ /// <example>
+ /// <p>This example causes the messages to be written to both file1.txt or file2.txt
+ /// </p>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/SplitGroup/NLog.config" />
+ /// <p>
+ /// The above examples assume just one target and a single rule. See below for
+ /// a programmatic configuration that's equivalent to the above config file:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/SplitGroup/Simple/Example.cs" />
+ /// </example>
+ [Target("SplitGroup", IgnoresLayout = true, IsCompound = true)]
+ public class SplitTarget: CompoundTargetBase
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="SplitTarget"/>.
+ /// </summary>
+ public SplitTarget()
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="SplitTarget"/> and
+ /// initializes the <see cref="Targets"/> collection to the
+ /// provided array of <see cref="Target"/> objects.
+ /// </summary>
+ public SplitTarget(params Target[] targets) : base(targets)
+ {
+ }
+
+ /// <summary>
+ /// Forwards the specified log event to all sub-targets.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ for (int i = 0; i < Targets.Count; ++i)
+ {
+ Targets[i].Write(logEvent);
+ }
+ }
+ }
+}
diff --git a/src/NLog/Targets/Console.cs b/src/NLog/Targets/Console.cs
new file mode 100644
index 0000000..85b74d1
--- /dev/null
+++ b/src/NLog/Targets/Console.cs
@@ -0,0 +1,128 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Writes logging messages to the console.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/Console/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/Console/Simple/Example.cs" />
+ /// </example>
+ [Target("Console")]
+ public sealed class ConsoleTarget: TargetWithLayoutHeaderAndFooter
+ {
+#if !NETCF
+ private bool _error = false;
+
+ /// <summary>
+ /// Send the logging messages to the standard error instead of the standard output.
+ /// </summary>
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ [System.ComponentModel.DefaultValue(false)]
+ public bool Error
+ {
+ get { return _error; }
+ set { _error = value; }
+ }
+#endif
+
+ /// <summary>
+ /// Writes the specified logging event to the Console.Out or
+ /// Console.Error depending on the value of the Error flag.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ /// <remarks>
+ /// Note that the Error option is not supported on .NET Compact Framework.
+ /// </remarks>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ Output(CompiledLayout.GetFormattedMessage(logEvent));
+ }
+
+ private void Output(string s)
+ {
+#if !NETCF
+ if (Error)
+ {
+ Console.Error.WriteLine(s);
+ }
+ else
+ {
+ Console.Out.WriteLine(s);
+ }
+#else
+ Console.WriteLine(s);
+#endif
+ }
+
+ /// <summary>
+ /// Initializes the target.
+ /// </summary>
+ public override void Initialize()
+ {
+ base.Initialize();
+ if (CompiledHeader != null)
+ {
+ Output(CompiledHeader.GetFormattedMessage(LogEventInfo.CreateNullEvent()));
+ }
+ }
+
+ /// <summary>
+ /// Closes the target and releases any unmanaged resources.
+ /// </summary>
+ protected internal override void Close()
+ {
+ if (CompiledFooter != null)
+ {
+ Output(CompiledFooter.GetFormattedMessage(LogEventInfo.CreateNullEvent()));
+ }
+ base.Close();
+ }
+ }
+}
diff --git a/src/NLog/Targets/Database.cs b/src/NLog/Targets/Database.cs
new file mode 100644
index 0000000..f7893f5
--- /dev/null
+++ b/src/NLog/Targets/Database.cs
@@ -0,0 +1,439 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Diagnostics;
+using System.Reflection;
+using System.Data;
+using System.Collections;
+
+using NLog.Internal;
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Writes logging messages to the database using an ADO.NET provider.
+ /// </summary>
+ /// <example>
+ /// <para>
+ /// The configuration is dependent on the database type, because
+ /// there are differnet methods of specifying connection string, SQL
+ /// command and command parameters.
+ /// </para>
+ /// <para>MS SQL Server using System.Data.SqlClient:</para>
+ /// <code lang="XML" src="examples/targets/Configuration File/Database/MSSQL/NLog.config" height="450" />
+ ///
+ /// <para>Oracle using System.Data.OracleClient:</para>
+ /// <code lang="XML" src="examples/targets/Configuration File/Database/Oracle.Native/NLog.config" height="350" />
+ ///
+ /// <para>Oracle using System.Data.OleDbClient:</para>
+ /// <code lang="XML" src="examples/targets/Configuration File/Database/Oracle.OleDb/NLog.config" height="350" />
+ ///
+ /// <para>To set up the log target programmatically use code like this (an equivalent of MSSQL configuration):</para>
+ /// <code lang="C#" src="examples/targets/Configuration API/Database/MSSQL/Example.cs" height="630" />
+ /// </example>
+ [Target("Database", IgnoresLayout=true)]
+ public sealed class DatabaseTarget: Target
+ {
+ private Assembly _system_data_assembly = typeof(IDbConnection).Assembly;
+ private Type _connectionType = null;
+ private bool _keepConnection = true;
+ private bool _useTransaction = false;
+ private Layout _connectionString = null;
+ private Layout _dbHostLayout = new Layout(".");
+ private Layout _dbUserNameLayout = null;
+ private Layout _dbPasswordLayout = null;
+ private Layout _dbDatabaseLayout = null;
+ private Layout _compiledCommandTextLayout = null;
+ private DatabaseParameterInfoCollection _parameters = new DatabaseParameterInfoCollection();
+ private IDbConnection _activeConnection = null;
+ private string _connectionStringCache = null;
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="DatabaseTarget"/> object and sets
+ /// the default values of some properties;
+ /// </summary>
+ public DatabaseTarget()
+ {
+ DBProvider = "sqlserver";
+ }
+
+ /// <summary>
+ /// The name of the database provider. It can be:
+ /// <c>sqlserver, mssql, microsoft, msde</c> (all for MSSQL database), <c>oledb, odbc</c> or other name in which case
+ /// it's treated as a fully qualified type name of the data provider *Connection class.
+ /// </summary>
+ [RequiredParameter]
+ [System.ComponentModel.DefaultValue("sqlserver")]
+ public string DBProvider
+ {
+ get { return _connectionType.FullName; }
+ set
+ {
+ switch (value)
+ {
+ case "sqlserver":
+ case "mssql":
+ case "microsoft":
+ case "msde":
+ _connectionType = _system_data_assembly.GetType("System.Data.SqlClient.SqlConnection");
+ break;
+
+ case "oledb":
+ _connectionType = _system_data_assembly.GetType("System.Data.OleDb.OleDbConnection");
+ break;
+
+ case "odbc":
+ _connectionType = _system_data_assembly.GetType("System.Data.Odbc.OdbcConnection");
+ break;
+
+ default:
+ _connectionType = Type.GetType(value);
+ break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The connection string. When provided, it overrides the values
+ /// specified in DBHost, DBUserName, DBPassword, DBDatabase.
+ /// </summary>
+ [AcceptsLayout]
+ public string ConnectionString
+ {
+ get { return Convert.ToString(_connectionString); }
+ set { _connectionString = new Layout(value); }
+ }
+
+ /// <summary>
+ /// Keep the database connection open between the log events.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool KeepConnection
+ {
+ get { return _keepConnection; }
+ set { _keepConnection = value; }
+ }
+
+ /// <summary>
+ /// Use database transactions. Some data providers require this.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool UseTransactions
+ {
+ get
+ {
+ return _useTransaction;
+
+ }
+ set { _useTransaction = value; }
+ }
+
+ /// <summary>
+ /// The database host name. If the ConnectionString is not provided
+ /// this value will be used to construct the "Server=" part of the
+ /// connection string.
+ /// </summary>
+ [AcceptsLayout]
+ public string DBHost
+ {
+ get { return Convert.ToString(_dbHostLayout); }
+ set { _dbHostLayout = new Layout(value); }
+ }
+
+ /// <summary>
+ /// The database host name. If the ConnectionString is not provided
+ /// this value will be used to construct the "Server=" part of the
+ /// connection string.
+ /// </summary>
+ public Layout DBHostLayout
+ {
+ get { return _dbHostLayout; }
+ set { _dbHostLayout = value; }
+ }
+
+ /// <summary>
+ /// The database user name. If the ConnectionString is not provided
+ /// this value will be used to construct the "User ID=" part of the
+ /// connection string.
+ /// </summary>
+ [AcceptsLayout]
+ public string DBUserName
+ {
+ get { return Convert.ToString(_dbUserNameLayout); }
+ set { _dbUserNameLayout = new Layout(value); }
+ }
+
+ /// <summary>
+ /// The database user name. If the ConnectionString is not provided
+ /// this value will be used to construct the "User ID=" part of the
+ /// connection string.
+ /// </summary>
+ public Layout DBUserNameLayout
+ {
+ get { return _dbUserNameLayout; }
+ set { _dbUserNameLayout = value; }
+ }
+
+ /// <summary>
+ /// The database password. If the ConnectionString is not provided
+ /// this value will be used to construct the "Password=" part of the
+ /// connection string.
+ /// </summary>
+ [AcceptsLayout]
+ public string DBPassword
+ {
+ get { return Convert.ToString(_dbPasswordLayout); }
+ set { _dbPasswordLayout = new Layout(value); }
+ }
+
+ /// <summary>
+ /// The database password. If the ConnectionString is not provided
+ /// this value will be used to construct the "Password=" part of the
+ /// connection string.
+ /// </summary>
+ public Layout DBPasswordLayout
+ {
+ get { return _dbPasswordLayout; }
+ set { _dbPasswordLayout = value; }
+ }
+
+ /// <summary>
+ /// The database name. If the ConnectionString is not provided
+ /// this value will be used to construct the "Database=" part of the
+ /// connection string.
+ /// </summary>
+ [AcceptsLayout]
+ public string DBDatabase
+ {
+ get { return Convert.ToString(_dbDatabaseLayout); }
+ set { _dbDatabaseLayout = new Layout(value); }
+ }
+
+ /// <summary>
+ /// The database name. If the ConnectionString is not provided
+ /// this value will be used to construct the "Database=" part of the
+ /// connection string.
+ /// </summary>
+ public Layout DBDatabaseLayout
+ {
+ get { return _dbDatabaseLayout; }
+ set { _dbDatabaseLayout = value; }
+ }
+
+ /// <summary>
+ /// The text of the SQL command to be run on each log level.
+ /// </summary>
+ /// <remarks>
+ /// Typically this is a SQL INSERT statement or a stored procedure call.
+ /// It should use the database-specific parameters (marked as <c>@parameter</c>
+ /// for SQL server or <c>:parameter</c> for Oracle, other data providers
+ /// have their own notation) and not the layout renderers,
+ /// because the latter is prone to SQL injection attacks.
+ /// The layout renderers should be specified as <parameters />> instead.
+ /// </remarks>
+ [AcceptsLayout]
+ [RequiredParameter]
+ public string CommandText
+ {
+ get { return Convert.ToString(_compiledCommandTextLayout); }
+ set { _compiledCommandTextLayout = new Layout(value); }
+ }
+
+ /// <summary>
+ /// The text of the SQL command to be run on each log level.
+ /// </summary>
+ /// <remarks>
+ /// Typically this is a SQL INSERT statement or a stored procedure call.
+ /// It should use the database-specific parameters (marked as <c>@parameter</c>
+ /// for SQL server or <c>:parameter</c> for Oracle, other data providers
+ /// have their own notation) and not the layout renderers,
+ /// because the latter is prone to SQL injection attacks.
+ /// The layout renderers should be specified as <parameters />< instead.
+ /// </remarks>
+ public Layout CommandTextLayout
+ {
+ get { return _compiledCommandTextLayout; }
+ set { _compiledCommandTextLayout = value; }
+ }
+
+ /// <summary>
+ /// The collection of paramters. Each parameter contains a mapping
+ /// between NLog layout and a database named or positional parameter.
+ /// </summary>
+ [ArrayParameter(typeof(DatabaseParameterInfo), "parameter")]
+ public DatabaseParameterInfoCollection Parameters
+ {
+ get { return _parameters; }
+ }
+
+ /// <summary>
+ /// Writes the specified logging event to the database. It creates
+ /// a new database command, prepares parameters for it by calculating
+ /// layouts and executes the command.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ if (_keepConnection)
+ {
+ lock(this)
+ {
+ if (_activeConnection == null)
+ _activeConnection = OpenConnection(logEvent);
+ DoAppend(logEvent);
+ }
+ }
+ else
+ {
+ try
+ {
+ _activeConnection = OpenConnection(logEvent);
+ DoAppend(logEvent);
+ }
+ finally
+ {
+ if (_activeConnection != null)
+ {
+ _activeConnection.Close();
+ _activeConnection = null;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ base.PopulateLayouts (layouts);
+
+ if (DBHostLayout != null) DBHostLayout.PopulateLayouts(layouts);
+ if (DBUserNameLayout != null) DBUserNameLayout.PopulateLayouts(layouts);
+ if (DBDatabaseLayout != null) DBDatabaseLayout.PopulateLayouts(layouts);
+ if (DBPasswordLayout != null) DBPasswordLayout.PopulateLayouts(layouts);
+ if (CommandTextLayout != null) CommandTextLayout.PopulateLayouts(layouts);
+
+ for (int i = 0; i < Parameters.Count; ++i)
+ {
+ if (Parameters[i].CompiledLayout != null)
+ Parameters[i].CompiledLayout.PopulateLayouts(layouts);
+ }
+ }
+
+ private void DoAppend(LogEventInfo logEvent)
+ {
+ IDbCommand command = _activeConnection.CreateCommand();
+ command.CommandText = CommandTextLayout.GetFormattedMessage(logEvent);
+ foreach (DatabaseParameterInfo par in Parameters)
+ {
+ IDbDataParameter p = command.CreateParameter();
+ p.Direction = ParameterDirection.Input;
+ if (par.Name != null)
+ p.ParameterName = par.Name;
+ if (par.Size != 0)
+ p.Size = par.Size;
+ if (par.Precision != 0)
+ p.Precision = par.Precision;
+ if (par.Scale != 0)
+ p.Scale = par.Scale;
+ p.Value = par.CompiledLayout.GetFormattedMessage(logEvent);
+ command.Parameters.Add(p);
+ }
+ command.ExecuteNonQuery();
+ }
+
+ private IDbConnection OpenConnection(LogEventInfo logEvent)
+ {
+ ConstructorInfo constructor = _connectionType.GetConstructor(new Type[]
+ {
+ typeof(string)
+ }
+
+ );
+ IDbConnection retVal = (IDbConnection)constructor.Invoke(new object[]
+ {
+ BuildConnectionString(logEvent)
+ }
+
+ );
+
+ if (retVal != null)
+ retVal.Open();
+
+ return retVal;
+ }
+
+ private string BuildConnectionString(LogEventInfo logEvent)
+ {
+ if (_connectionStringCache != null)
+ return _connectionStringCache;
+
+ if (_connectionString != null)
+ return _connectionString.GetFormattedMessage(logEvent);
+
+ StringBuilder sb = new StringBuilder();
+
+ sb.Append("Server=");
+ sb.Append(DBHostLayout.GetFormattedMessage(logEvent));
+ sb.Append(";");
+ if (DBUserNameLayout == null)
+ {
+ sb.Append("Trusted_Connection=SSPI;");
+ }
+ else
+ {
+ sb.Append("User id=");
+ sb.Append(DBUserNameLayout.GetFormattedMessage(logEvent));
+ sb.Append(";Password=");
+ sb.Append(DBPasswordLayout.GetFormattedMessage(logEvent));
+ sb.Append(";");
+ }
+
+ if (DBDatabaseLayout != null)
+ {
+ sb.Append("Database=");
+ sb.Append(DBDatabaseLayout.GetFormattedMessage(logEvent));
+ }
+
+ _connectionStringCache = sb.ToString();
+
+ InternalLogger.Debug("Connection string: {0}", _connectionStringCache);
+ return _connectionStringCache;
+ }
+ }
+}
diff --git a/src/NLog/Targets/DatabaseParameterInfo.cs b/src/NLog/Targets/DatabaseParameterInfo.cs
new file mode 100644
index 0000000..8647041
--- /dev/null
+++ b/src/NLog/Targets/DatabaseParameterInfo.cs
@@ -0,0 +1,132 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Diagnostics;
+using System.Reflection;
+using System.Data;
+using System.Collections;
+
+using NLog.Internal;
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Represents a parameter to a Database target.
+ /// </summary>
+ public class DatabaseParameterInfo
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="DatabaseParameterInfo"/>.
+ /// </summary>
+ public DatabaseParameterInfo(){}
+
+ /// <summary>
+ /// Creates a new instance of <see cref="DatabaseParameterInfo"/>
+ /// and sets Name and Layout properties to the specified values.
+ /// </summary>
+ public DatabaseParameterInfo(string name, string layout)
+ {
+ Name = name;
+ Layout = layout;
+ }
+
+ private Layout _compiledlayout;
+ private string _name;
+ private int _size = 0;
+ private byte _precision = 0;
+ private byte _scale = 0;
+
+ /// <summary>
+ /// Database parameter name.
+ /// </summary>
+ [RequiredParameter]
+ public string Name
+ {
+ get { return _name; }
+ set { _name = value; }
+ }
+
+ /// <summary>
+ /// The layout that should be use to calcuate the value for the parameter.
+ /// </summary>
+ [RequiredParameter]
+ [AcceptsLayout]
+ public string Layout
+ {
+ get { return _compiledlayout.Text; }
+ set { _compiledlayout = new Layout(value); }
+ }
+
+ /// <summary>
+ /// The compiled representation of the Layout property.
+ /// </summary>
+ public Layout CompiledLayout
+ {
+ get { return _compiledlayout; }
+ set { _compiledlayout = value; }
+ }
+
+ /// <summary>
+ /// Database parameter size.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(0)]
+ public int Size
+ {
+ get { return _size; }
+ set { _size = value; }
+ }
+
+ /// <summary>
+ /// Database parameter precision.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(0)]
+ public byte Precision
+ {
+ get { return _precision; }
+ set { _precision = value; }
+ }
+
+ /// <summary>
+ /// Database parameter scale.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(0)]
+ public byte Scale
+ {
+ get { return _scale; }
+ set { _scale = value; }
+ }
+ }
+}
diff --git a/src/NLog/Targets/DatabaseParameterInfoCollection.cs b/src/NLog/Targets/DatabaseParameterInfoCollection.cs
new file mode 100644
index 0000000..09fc002
--- /dev/null
+++ b/src/NLog/Targets/DatabaseParameterInfoCollection.cs
@@ -0,0 +1,249 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Diagnostics;
+using System.Reflection;
+using System.Data;
+using System.Collections;
+
+using NLog.Internal;
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A collection of elements of type DatabaseParameterInfo
+ /// </summary>
+ public class DatabaseParameterInfoCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the DatabaseParameterInfoCollection class.
+ /// </summary>
+ public DatabaseParameterInfoCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the DatabaseParameterInfoCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new DatabaseParameterInfoCollection.
+ /// </param>
+ public DatabaseParameterInfoCollection(DatabaseParameterInfo[]items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the DatabaseParameterInfoCollection class, containing elements
+ /// copied from another instance of DatabaseParameterInfoCollection
+ /// </summary>
+ /// <param name="items">
+ /// The DatabaseParameterInfoCollection whose elements are to be added to the new DatabaseParameterInfoCollection.
+ /// </param>
+ public DatabaseParameterInfoCollection(DatabaseParameterInfoCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this DatabaseParameterInfoCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this DatabaseParameterInfoCollection.
+ /// </param>
+ public virtual void AddRange(DatabaseParameterInfo[]items)
+ {
+ foreach (DatabaseParameterInfo item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another DatabaseParameterInfoCollection to the end of this DatabaseParameterInfoCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The DatabaseParameterInfoCollection whose elements are to be added to the end of this DatabaseParameterInfoCollection.
+ /// </param>
+ public virtual void AddRange(DatabaseParameterInfoCollection items)
+ {
+ foreach (DatabaseParameterInfo item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type DatabaseParameterInfo to the end of this DatabaseParameterInfoCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The DatabaseParameterInfo to be added to the end of this DatabaseParameterInfoCollection.
+ /// </param>
+ public virtual void Add(DatabaseParameterInfo value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic DatabaseParameterInfo value is in this DatabaseParameterInfoCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The DatabaseParameterInfo value to locate in this DatabaseParameterInfoCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this DatabaseParameterInfoCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(DatabaseParameterInfo value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this DatabaseParameterInfoCollection
+ /// </summary>
+ /// <param name="value">
+ /// The DatabaseParameterInfo value to locate in the DatabaseParameterInfoCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(DatabaseParameterInfo value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the DatabaseParameterInfoCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the DatabaseParameterInfo is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The DatabaseParameterInfo to insert.
+ /// </param>
+ public virtual void Insert(int index, DatabaseParameterInfo value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the DatabaseParameterInfo at the given index in this DatabaseParameterInfoCollection.
+ /// </summary>
+ public virtual DatabaseParameterInfo this[int index]
+ {
+ get { return (DatabaseParameterInfo)this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific DatabaseParameterInfo from this DatabaseParameterInfoCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The DatabaseParameterInfo value to remove from this DatabaseParameterInfoCollection.
+ /// </param>
+ public virtual void Remove(DatabaseParameterInfo value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by DatabaseParameterInfoCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(DatabaseParameterInfoCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public DatabaseParameterInfo Current
+ {
+ get { return (DatabaseParameterInfo)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (DatabaseParameterInfo)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this DatabaseParameterInfoCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual DatabaseParameterInfoCollection.Enumerator GetEnumerator()
+ {
+ return new DatabaseParameterInfoCollection.Enumerator(this);
+ }
+ }
+}
diff --git a/src/NLog/Targets/Debug.cs b/src/NLog/Targets/Debug.cs
new file mode 100644
index 0000000..b8b9607
--- /dev/null
+++ b/src/NLog/Targets/Debug.cs
@@ -0,0 +1,94 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+
+using System.Threading;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Counts logging messages but does not output them anywhere. Provides
+ /// the counter of logged messages and remembers the latest one.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/Debug/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/Debug/Simple/Example.cs" />
+ /// </example>
+ [Target("Debug")]
+ public sealed class DebugTarget: TargetWithLayout
+ {
+ private int _counter = 0;
+ private string _lastMessage = String.Empty;
+
+ /// <summary>
+ /// Increases the number of messages.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ _counter++;
+ _lastMessage = CompiledLayout.GetFormattedMessage(logEvent);
+ }
+
+ /// <summary>
+ /// The number of times this target has been called.
+ /// </summary>
+ public int Counter
+ {
+ get { return _counter; }
+ }
+
+ /// <summary>
+ /// The last message rendered by this target.
+ /// </summary>
+ public string LastMessage
+ {
+ get { return _lastMessage; }
+ }
+ }
+}
diff --git a/src/NLog/Targets/Debugger.cs b/src/NLog/Targets/Debugger.cs
new file mode 100644
index 0000000..5f3b415
--- /dev/null
+++ b/src/NLog/Targets/Debugger.cs
@@ -0,0 +1,105 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Diagnostics;
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Writes logging messages to the attached managed debugger (for example Visual Studio .NET or DbgCLR).
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/Debugger/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/Debugger/Simple/Example.cs" />
+ /// </example>
+ [Target("Debugger")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public sealed class DebuggerTarget: TargetWithLayoutHeaderAndFooter
+ {
+ static DebuggerTarget()
+ {
+ }
+ /// <summary>
+ /// Writes the specified logging event to the attached debugger.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ if (Debugger.IsLogging())
+ {
+ Debugger.Log(logEvent.Level.Ordinal, logEvent.LoggerName, CompiledLayout.GetFormattedMessage(logEvent) + "\n");
+ }
+ }
+
+ /// <summary>
+ /// Initializes the target.
+ /// </summary>
+ public override void Initialize()
+ {
+ base.Initialize();
+ if (CompiledHeader != null)
+ {
+ Debugger.Log(LogLevel.Off.Ordinal, "", CompiledHeader.GetFormattedMessage(LogEventInfo.CreateNullEvent()) + "\n");
+ }
+ }
+
+ /// <summary>
+ /// Closes the target and releases any unmanaged resources.
+ /// </summary>
+ protected internal override void Close()
+ {
+ if (CompiledFooter != null)
+ {
+ Debugger.Log(LogLevel.Off.Ordinal, "", CompiledFooter.GetFormattedMessage(LogEventInfo.CreateNullEvent()) + "\n");
+ }
+ base.Close();
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Targets/File.cs b/src/NLog/Targets/File.cs
new file mode 100644
index 0000000..2799c15
--- /dev/null
+++ b/src/NLog/Targets/File.cs
@@ -0,0 +1,1344 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Threading;
+using System.Collections;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Config;
+
+using NLog.Internal;
+using NLog.Internal.FileAppenders;
+#if !NETCF
+using System.Runtime.InteropServices;
+using NLog.Internal.Win32;
+#endif
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Writes logging messages to one or more files.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/File/Simple/NLog.config" />
+ /// <p>
+ /// You can use a single target to write to multiple files. The following
+ /// example writes each log message to a file named after its log level, so
+ /// it will create:
+ /// <c>Trace.log</c>, <c>Debug.log</c>, <c>Info.log</c>, <c>Warn.log</c>,
+ /// <c>Error.log</c>, <c>Fatal.log</c>
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/File/Multiple/NLog.config" />
+ /// <p>
+ /// The file names can be quite complex for the most demanding scenarios. This
+ /// example shows a way to create separate files for each day, user and log level.
+ /// As you can see, the possibilities are endless.
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/File/Multiple2/NLog.config" />
+ /// <p>
+ /// Depending on your usage scenario it may be useful to add an <a href="target.AsyncWrapper.html">asynchronous target wrapper</a>
+ /// around the file target. This way all your log messages
+ /// will be written in a separate thread so your main thread can finish
+ /// your work more quickly. Asynchronous logging is recommended
+ /// for multi-threaded server applications which run for a long time and
+ /// is not recommended for quickly-finishing command line applications.
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/File/Asynchronous/NLog.config" />
+ /// <p>
+ /// The above examples assume just one target and a single rule. See below for
+ /// a programmatic configuration that's equivalent to the above config file:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/File/Asynchronous/Example.cs" />
+ /// <p>
+ /// More configuration options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/File/Simple/Example.cs" />
+ /// <p>
+ /// File target can also do file archiving, meaning that the log file is automatically
+ /// moved to another place based on its size and time. This example demonstrates
+ /// file archiving based on size. Files after 10000 bytes are moved to a separate folder
+ /// and renamed log.00000.txt, log.00001.txt and so on.
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/File/Archive1/Example.cs" />
+ /// <p>
+ /// File archiving can also be done on date/time changes. For example, to create a new
+ /// archive file every minute use this code:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/File/Archive2/Example.cs" />
+ /// <p>
+ /// You can combine both methods as demonstrated here:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/File/Archive3/Example.cs" />
+ /// <p>
+ /// Note that file archiving works even when you use a single target instance
+ /// to write to multiple files, such as putting each log level in a separate place:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/File/Archive4/Example.cs" />
+ /// <p>
+ /// You can write texts using alternative layouts, such as CSV (comma-separated values).
+ /// This example writes files which are properly CSV-quoted (can handle messages with line breaks
+ /// and quotes)
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/File/CSV/Example.cs" />
+ /// <para>
+ /// This is the configuration file version:
+ /// </para>
+ /// <code lang="XML" src="examples/targets/Configuration File/File/CSV/NLog.config" />
+ /// </example>
+ [Target("File")]
+ public class FileTarget: TargetWithLayoutHeaderAndFooter, ICreateFileParameters
+ {
+ /// <summary>
+ /// Specifies the way archive numbering is performed.
+ /// </summary>
+ public enum ArchiveNumberingMode
+ {
+ /// <summary>
+ /// Sequence style numbering. The most recent archive has the highest number.
+ /// </summary>
+ Sequence,
+
+ /// <summary>
+ /// Rolling style numbering (the most recent is always #0 then #1, ..., #N
+ /// </summary>
+ Rolling,
+ }
+
+ /// <summary>
+ /// Modes of archiving files based on time.
+ /// </summary>
+ public enum ArchiveEveryMode
+ {
+ /// <summary>
+ /// Don't archive based on time.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// Archive every year.
+ /// </summary>
+ Year,
+
+ /// <summary>
+ /// Archive every month.
+ /// </summary>
+ Month,
+
+ /// <summary>
+ /// Archive daily.
+ /// </summary>
+ Day,
+
+ /// <summary>
+ /// Archive every hour.
+ /// </summary>
+ Hour,
+
+ /// <summary>
+ /// Archive every minute.
+ /// </summary>
+ Minute
+ }
+
+ /// <summary>
+ /// Line ending mode.
+ /// </summary>
+ public enum LineEndingMode
+ {
+ /// <summary>
+ /// Insert platform-dependent end-of-line sequence after each line.
+ /// </summary>
+ Default,
+
+ /// <summary>
+ /// Insert CR LF sequence (ASCII 13, ASCII 10) after each line.
+ /// </summary>
+ CRLF,
+
+ /// <summary>
+ /// Insert CR character (ASCII 13) after each line.
+ /// </summary>
+ CR,
+
+ /// <summary>
+ /// Insert LF character (ASCII 10) after each line.
+ /// </summary>
+ LF,
+
+ /// <summary>
+ /// Don't insert any line ending.
+ /// </summary>
+ None,
+ }
+
+ private Layout _fileNameLayout;
+ private bool _createDirs = true;
+ private bool _keepFileOpen = false;
+ private System.Text.Encoding _encoding = System.Text.Encoding.Default;
+#if NETCF
+ private string _newLine = "\r\n";
+#else
+ private string _newLine = Environment.NewLine;
+#endif
+ private LineEndingMode _lineEndingMode = LineEndingMode.Default;
+
+ private bool _autoFlush = true;
+ private bool _concurrentWrites = true;
+ private bool _networkWrites = false;
+ private int _concurrentWriteAttempts = 10;
+ private int _bufferSize = 32768;
+ private int _concurrentWriteAttemptDelay = 1;
+ private LogEventComparer _logEventComparer;
+ private Layout _autoArchiveFileName = null;
+ private int _maxArchiveFiles = 9;
+ private long _archiveAboveSize = -1;
+ private ArchiveEveryMode _archiveEvery = ArchiveEveryMode.None;
+ private int _openFileCacheSize = 5;
+ private IFileAppenderFactory _appenderFactory;
+ private BaseFileAppender[] _recentAppenders;
+ private ArchiveNumberingMode _archiveNumbering = ArchiveNumberingMode.Sequence;
+ private Timer _autoClosingTimer = null;
+ private int _openFileCacheTimeout = -1;
+ private bool _deleteOldFileOnStartup = false;
+ private bool _replaceFileContentsOnEachWrite = false;
+ private bool _enableFileDelete = true;
+ private Hashtable _initializedFiles = new Hashtable();
+ private int _initializedFilesCounter = 0;
+#if !NETCF
+ private Win32FileAttributes _fileAttributes = Win32FileAttributes.Normal;
+#endif
+
+ /// <summary>
+ /// Creates a new instance of <see cref="FileTarget"/>.
+ /// </summary>
+ public FileTarget()
+ {
+ _logEventComparer = new LogEventComparer(this);
+ }
+
+ /// <summary>
+ /// The name of the file to write to.
+ /// </summary>
+ /// <remarks>
+ /// This FileName string is a layout which may include instances of layout renderers.
+ /// This lets you use a single target to write to multiple files.
+ /// </remarks>
+ /// <example>
+ /// The following value makes NLog write logging events to files based on the log level in the directory where
+ /// the application runs.
+ /// <code>${basedir}/${level}.log</code>
+ /// All <c>Debug</c> messages will go to <c>Debug.log</c>, all <c>Info</c> messages will go to <c>Info.log</c> and so on.
+ /// You can combine as many of the layout renderers as you want to produce an arbitrary log file name.
+ /// </example>
+ [RequiredParameter]
+ [AcceptsLayout]
+ public string FileName
+ {
+ get { return _fileNameLayout.Text; }
+ set { _fileNameLayout = new Layout(value); }
+ }
+
+ /// <summary>
+ /// Create directories if they don't exist.
+ /// </summary>
+ /// <remarks>
+ /// Setting this to false may improve performance a bit, but you'll receive an error
+ /// when attempting to write to a directory that's not present.
+ /// </remarks>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool CreateDirs
+ {
+ get { return _createDirs; }
+ set { _createDirs = value; }
+ }
+
+ /// <summary>
+ /// The number of files to be kept open. Setting this to a higher value may improve performance
+ /// in a situation where a single File target is writing to many files
+ /// (such as splitting by level or by logger).
+ /// </summary>
+ /// <remarks>
+ /// The files are managed on a LRU (least recently used) basis, which flushes
+ /// the files that have not been used for the longest period of time should the
+ /// cache become full. As a rule of thumb, you shouldn't set this parameter to
+ /// a very high value. A number like 10-15 shouldn't be exceeded, because you'd
+ /// be keeping a large number of files open which consumes system resources.
+ /// </remarks>
+ [System.ComponentModel.DefaultValue(5)]
+ public int OpenFileCacheSize
+ {
+ get { return _openFileCacheSize; }
+ set { _openFileCacheSize = value; }
+ }
+
+ /// <summary>
+ /// Maximum number of seconds that files are kept open. If this number is negative.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(-1)]
+ public int OpenFileCacheTimeout
+ {
+ get { return _openFileCacheTimeout; }
+ set { _openFileCacheTimeout = value; }
+ }
+
+ /// <summary>
+ /// Delete old log file on startup.
+ /// </summary>
+ /// <remarks>
+ /// This option works only when the "fileName" parameter denotes a single file.
+ /// </remarks>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool DeleteOldFileOnStartup
+ {
+ get { return _deleteOldFileOnStartup; }
+ set { _deleteOldFileOnStartup = value; }
+ }
+
+ /// <summary>
+ /// Replace file contents on each write instead of appending log message at the end.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool ReplaceFileContentsOnEachWrite
+ {
+ get { return _replaceFileContentsOnEachWrite; }
+ set { _replaceFileContentsOnEachWrite = value; }
+ }
+
+ /// <summary>
+ /// Keep log file open instead of opening and closing it on each logging event.
+ /// </summary>
+ /// <remarks>
+ /// Setting this property to <c>True</c> helps improve performance.
+ /// </remarks>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool KeepFileOpen
+ {
+ get { return _keepFileOpen; }
+ set { _keepFileOpen = value; }
+ }
+
+ /// <summary>
+ /// Enable log file(s) to be deleted.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool EnableFileDelete
+ {
+ get { return _enableFileDelete; }
+ set { _enableFileDelete = value; }
+ }
+
+#if !NETCF
+ /// <summary>
+ /// File attributes (Windows only).
+ /// </summary>
+ public Win32FileAttributes FileAttributes
+ {
+ get { return _fileAttributes; }
+ set { _fileAttributes = value; }
+ }
+#endif
+
+ /// <summary>
+ /// Gets the characters that are appended after each line.
+ /// </summary>
+ protected string NewLineChars
+ {
+ get { return _newLine; }
+ }
+ /// <summary>
+ /// Line ending mode.
+ /// </summary>
+ public LineEndingMode LineEnding
+ {
+ get { return _lineEndingMode; }
+ set
+ {
+ _lineEndingMode = value;
+ switch (value)
+ {
+ case LineEndingMode.CR:
+ _newLine = "\r";
+ break;
+
+ case LineEndingMode.LF:
+ _newLine = "\n";
+ break;
+
+ case LineEndingMode.CRLF:
+ _newLine = "\r\n";
+ break;
+
+ case LineEndingMode.Default:
+#if NETCF
+ _newLine = "\r\n";
+#else
+ _newLine = Environment.NewLine;
+#endif
+ break;
+
+ case LineEndingMode.None:
+ _newLine = "";
+ break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Automatically flush the file buffers after each log message.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool AutoFlush
+ {
+ get { return _autoFlush; }
+ set { _autoFlush = value; }
+ }
+
+ /// <summary>
+ /// Log file buffer size in bytes.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(32768)]
+ public int BufferSize
+ {
+ get { return _bufferSize; }
+ set { _bufferSize = value; }
+ }
+
+ /// <summary>
+ /// File encoding.</summary>
+ /// <remarks>
+ /// Can be any encoding name supported by System.Text.Encoding.GetEncoding() e.g. <c>windows-1252</c>, <c>iso-8859-2</c>.
+ /// </remarks>
+ public string Encoding
+ {
+ get { return _encoding.WebName; }
+ set { _encoding = System.Text.Encoding.GetEncoding(value); }
+ }
+
+ /// <summary>
+ /// Enables concurrent writes to the log file by multiple processes on the same host.
+ /// </summary>
+ /// <remarks>
+ /// This makes multi-process logging possible. NLog uses a special technique
+ /// that lets it keep the files open for writing.
+ /// </remarks>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool ConcurrentWrites
+ {
+ get { return _concurrentWrites; }
+ set { _concurrentWrites = value; }
+ }
+
+ /// <summary>
+ /// Disables open-fi
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool NetworkWrites
+ {
+ get { return _networkWrites; }
+ set { _networkWrites = value; }
+ }
+
+ /// <summary>
+ /// The number of times the write is appended on the file before NLog
+ /// discards the log message.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(10)]
+ public int ConcurrentWriteAttempts
+ {
+ get { return _concurrentWriteAttempts; }
+ set { _concurrentWriteAttempts = value; }
+ }
+
+ /// <summary>
+ /// Automatically archive log files that exceed the specified size in bytes.
+ /// </summary>
+ /// <remarks>
+ /// Caution: Enabling this option can considerably slow down your file
+ /// logging in multi-process scenarios. If only one process is going to
+ /// be writing to the file, consider setting <c>ConcurrentWrites</c>
+ /// to <c>false</c> for maximum performance.
+ /// </remarks>
+ public long ArchiveAboveSize
+ {
+ get { return _archiveAboveSize; }
+ set { _archiveAboveSize = value; }
+ }
+
+ /// <summary>
+ /// Automatically archive log files every time the specified time passes.
+ /// Possible options are: <c>year</c>, <c>month</c>, <c>day</c>, <c>hour</c>, <c>minute</c>. Files are
+ /// moved to the archive as part of the write operation if the current period of time changes. For example
+ /// if the current <c>hour</c> changes from 10 to 11, the first write that will occur
+ /// on or after 11:00 will trigger the archiving.
+ /// </summary>
+ /// <remarks>
+ /// <p>
+ /// Caution: Enabling this option can considerably slow down your file
+ /// logging in multi-process scenarios. If only one process is going to
+ /// be writing to the file, consider setting <c>ConcurrentWrites</c>
+ /// to <c>false</c> for maximum performance.
+ /// </p>
+ /// </remarks>
+ public ArchiveEveryMode ArchiveEvery
+ {
+ get { return _archiveEvery; }
+ set { _archiveEvery = value; }
+ }
+
+ /// <summary>
+ /// The name of the file to be used for an archive.
+ /// It may contain a special placeholder {#####}
+ /// that will be replaced with a sequence of numbers depending on
+ /// the archiving strategy. The number of hash characters used determines
+ /// the number of numerical digits to be used for numbering files.
+ /// </summary>
+ [AcceptsLayout]
+ public string ArchiveFileName
+ {
+ get
+ {
+ if (_autoArchiveFileName == null)
+ return null;
+ return _autoArchiveFileName.Text;
+ }
+ set { _autoArchiveFileName = new Layout(value); }
+ }
+
+ /// <summary>
+ /// The delay in milliseconds to wait before attempting to write to the file again.
+ /// </summary>
+ /// <remarks>
+ /// The actual delay is a random value between 0 and the value specified
+ /// in this parameter. On each failed attempt the delay base is doubled
+ /// up to <see cref="ConcurrentWriteAttempts" /> times.
+ /// </remarks>
+ /// <example>
+ /// Assuming that ConcurrentWriteAttemptDelay is 10 the time to wait will be:<p/>
+ /// a random value between 0 and 10 milliseconds - 1st attempt<br/>
+ /// a random value between 0 and 20 milliseconds - 2nd attempt<br/>
+ /// a random value between 0 and 40 milliseconds - 3rd attempt<br/>
+ /// a random value between 0 and 80 milliseconds - 4th attempt<br/>
+ /// ...<p/>
+ /// and so on.
+ /// </example>
+ [System.ComponentModel.DefaultValue(1)]
+ public int ConcurrentWriteAttemptDelay
+ {
+ get { return _concurrentWriteAttemptDelay; }
+ set { _concurrentWriteAttemptDelay = value; }
+ }
+
+ /// <summary>
+ /// Maximum number of archive files that should be kept.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(9)]
+ public int MaxArchiveFiles
+ {
+ get { return _maxArchiveFiles; }
+ set { _maxArchiveFiles = value; }
+ }
+
+ /// <summary>
+ /// Determines the way file archives are numbered.
+ /// </summary>
+ public ArchiveNumberingMode ArchiveNumbering
+ {
+ get { return _archiveNumbering; }
+ set { _archiveNumbering = value; }
+ }
+
+ private void RecursiveRollingRename(string fileName, string pattern, int archiveNumber)
+ {
+ if (archiveNumber >= MaxArchiveFiles)
+ {
+ File.Delete(fileName);
+ return;
+ }
+
+ if (!File.Exists(fileName))
+ return;
+
+ string newFileName = ReplaceNumber(pattern, archiveNumber);
+ if (File.Exists(fileName))
+ RecursiveRollingRename(newFileName, pattern, archiveNumber + 1);
+
+ if (InternalLogger.IsTraceEnabled)
+ InternalLogger.Trace("Renaming {0} to {1}", fileName, newFileName);
+ try
+ {
+ File.Move(fileName, newFileName);
+ }
+ catch (DirectoryNotFoundException)
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(newFileName));
+ File.Move(fileName, newFileName);
+ }
+ }
+
+ private string ReplaceNumber(string pattern, int value)
+ {
+ int firstPart = pattern.IndexOf("{#");
+ int lastPart = pattern.IndexOf("#}") + 2;
+ int numDigits = lastPart - firstPart - 2;
+
+ return pattern.Substring(0, firstPart) + Convert.ToString(value, 10).PadLeft(numDigits, '0') + pattern.Substring(lastPart);
+ }
+
+ private void SequentialArchive(string fileName, string pattern)
+ {
+ string baseNamePattern = Path.GetFileName(pattern);
+
+ //Console.WriteLine("baseNamePatern: {0}", baseNamePattern);
+
+ int firstPart = baseNamePattern.IndexOf("{#");
+ int lastPart = baseNamePattern.IndexOf("#}") + 2;
+ int trailerLength = baseNamePattern.Length - lastPart;
+
+ string fileNameMask = baseNamePattern.Substring(0, firstPart) + "*" + baseNamePattern.Substring(lastPart);
+
+ //Console.WriteLine("fileNameMask: {0}", fileNameMask);
+ string dirName = Path.GetDirectoryName(Path.GetFullPath(pattern));
+ int nextNumber = -1;
+ int minNumber = -1;
+
+ Hashtable number2name = new Hashtable();
+
+ try
+ {
+ // Console.WriteLine("dirName: {0}", dirName);
+ foreach (string s in Directory.GetFiles(dirName, fileNameMask))
+ {
+ string baseName = Path.GetFileName(s);
+ string number = baseName.Substring(firstPart, baseName.Length - trailerLength - firstPart);
+ int num;
+
+ try
+ {
+ num = Convert.ToInt32(number);
+ }
+ catch (FormatException)
+ {
+ continue;
+ }
+
+ nextNumber = Math.Max(nextNumber, num);
+ if (minNumber != -1)
+ {
+ minNumber = Math.Min(minNumber, num);
+ }
+ else
+ {
+ minNumber = num;
+ }
+
+ number2name[num] = s;
+ }
+ nextNumber++;
+ }
+ catch (DirectoryNotFoundException)
+ {
+ Directory.CreateDirectory(dirName);
+ nextNumber = 0;
+ }
+
+ if (minNumber != -1)
+ {
+ int minNumberToKeep = nextNumber - _maxArchiveFiles + 1;
+ for (int i = minNumber; i < minNumberToKeep; ++i)
+ {
+ string s = (string)number2name[i];
+ if (s != null)
+ {
+ File.Delete(s);
+ }
+ }
+ }
+
+ string newFileName = ReplaceNumber(pattern, nextNumber);
+ File.Move(fileName, newFileName);
+ }
+
+ private void DoAutoArchive(string fileName, LogEventInfo ev)
+ {
+ FileInfo fi = new FileInfo(fileName);
+ if (!fi.Exists)
+ return;
+
+ // Console.WriteLine("DoAutoArchive({0})", fileName);
+
+ string fileNamePattern;
+
+ if (_autoArchiveFileName == null)
+ {
+ string ext = Path.GetExtension(fileName);
+ fileNamePattern = Path.ChangeExtension(fi.FullName, ".{#}" + ext);
+
+ }
+ else
+ {
+ fileNamePattern = _autoArchiveFileName.GetFormattedMessage(ev);
+ }
+
+ switch (ArchiveNumbering)
+ {
+ case ArchiveNumberingMode.Rolling:
+ RecursiveRollingRename(fi.FullName, fileNamePattern, 0);
+ break;
+
+ case ArchiveNumberingMode.Sequence:
+ SequentialArchive(fi.FullName, fileNamePattern);
+ break;
+ }
+ }
+
+ private bool ShouldAutoArchive(string fileName, LogEventInfo ev, int upcomingWriteSize)
+ {
+ if (_archiveAboveSize == -1 && _archiveEvery == ArchiveEveryMode.None)
+ return false;
+
+ DateTime lastWriteTime;
+ long fileLength;
+
+ if (!GetFileInfo(fileName, out lastWriteTime, out fileLength))
+ return false;
+
+ if (_archiveAboveSize != -1)
+ {
+ if (fileLength + upcomingWriteSize > _archiveAboveSize)
+ return true;
+ }
+
+ if (_archiveEvery != ArchiveEveryMode.None)
+ {
+ string formatString;
+
+ switch (_archiveEvery)
+ {
+ case ArchiveEveryMode.Year:
+ formatString = "yyyy";
+ break;
+
+ case ArchiveEveryMode.Month:
+ formatString = "yyyyMM";
+ break;
+
+ default:
+ case ArchiveEveryMode.Day:
+ formatString = "yyyyMMdd";
+ break;
+
+ case ArchiveEveryMode.Hour:
+ formatString = "yyyyMMddHH";
+ break;
+
+ case ArchiveEveryMode.Minute:
+ formatString = "yyyyMMddHHmm";
+ break;
+ }
+
+ string ts = lastWriteTime.ToString(formatString);
+ string ts2 = ev.TimeStamp.ToString(formatString);
+
+ if (ts != ts2)
+ return true;
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ base.PopulateLayouts (layouts);
+ _fileNameLayout.PopulateLayouts(layouts);
+ }
+
+ /// <summary>
+ /// Formats the log event for write.
+ /// </summary>
+ /// <param name="logEvent">The log event to be formatted.</param>
+ /// <returns>A string representation of the log event.</returns>
+ protected virtual string GetFormattedMessage(LogEventInfo logEvent)
+ {
+ return CompiledLayout.GetFormattedMessage(logEvent);
+ }
+
+ /// <summary>
+ /// Gets the bytes to be written to the file.
+ /// </summary>
+ /// <param name="logEvent">log event</param>
+ /// <returns>array of bytes that are ready to be written</returns>
+ protected virtual byte[] GetBytesToWrite(LogEventInfo logEvent)
+ {
+ string renderedText = GetFormattedMessage(logEvent) + NewLineChars;
+ return TransformBytes(_encoding.GetBytes(renderedText));
+ }
+
+ /// <summary>
+ /// Writes the specified logging event to a file specified in the FileName
+ /// parameter.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ lock (this)
+ {
+ string fileName = _fileNameLayout.GetFormattedMessage(logEvent);
+ byte[] bytes = GetBytesToWrite(logEvent);
+
+ if (ShouldAutoArchive(fileName, logEvent, bytes.Length))
+ {
+ InvalidateCacheItem(fileName);
+ DoAutoArchive(fileName, logEvent);
+ }
+
+ WriteToFile(fileName, bytes, false);
+ }
+ }
+
+
+ /// <summary>
+ /// Writes the specified array of logging events to a file specified in the FileName
+ /// parameter.
+ /// </summary>
+ /// <param name="logEvents">An array of <see cref="LogEventInfo "/> objects.</param>
+ /// <remarks>
+ /// This function makes use of the fact that the events are batched by sorting
+ /// the requests by filename. This optimizes the number of open/close calls
+ /// and can help improve performance.
+ /// </remarks>
+ protected internal override void Write(LogEventInfo[] logEvents)
+ {
+ if (_fileNameLayout.IsAppDomainFixed)
+ {
+ foreach (LogEventInfo lei in logEvents)
+ Write(lei);
+ return;
+ }
+
+ Array.Sort(logEvents, 0, logEvents.Length, _logEventComparer);
+
+ lock (this)
+ {
+ string currentFileName = null;
+ MemoryStream ms = new MemoryStream();
+ LogEventInfo firstLogEvent = null;
+
+ for (int i = 0; i < logEvents.Length; ++i)
+ {
+ LogEventInfo logEvent = logEvents[i];
+ string logEventFileName = _fileNameLayout.GetFormattedMessage(logEvent);
+ if (logEventFileName != currentFileName)
+ {
+ if (currentFileName != null)
+ {
+ if (ShouldAutoArchive(currentFileName, firstLogEvent, (int)ms.Length))
+ {
+ WriteFooterAndUninitialize(currentFileName);
+ InvalidateCacheItem(currentFileName);
+ DoAutoArchive(currentFileName, firstLogEvent);
+ }
+
+ WriteToFile(currentFileName, ms.ToArray(), false);
+ }
+ currentFileName = logEventFileName;
+ firstLogEvent = logEvent;
+ ms.SetLength(0);
+ ms.Position = 0;
+ }
+
+ byte[] bytes = GetBytesToWrite(logEvent);
+ ms.Write(bytes, 0, bytes.Length);
+ }
+ if (currentFileName != null)
+ {
+ if (ShouldAutoArchive(currentFileName, firstLogEvent, (int)ms.Length))
+ {
+ WriteFooterAndUninitialize(currentFileName);
+ InvalidateCacheItem(currentFileName);
+ DoAutoArchive(currentFileName, firstLogEvent);
+ }
+
+ WriteToFile(currentFileName, ms.ToArray(), false);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Initializes file logging by creating data structures that
+ /// enable efficient multi-file logging.
+ /// </summary>
+ public override void Initialize()
+ {
+ base.Initialize ();
+
+ if (!KeepFileOpen)
+ {
+ _appenderFactory = RetryingMultiProcessFileAppender.TheFactory;
+ }
+ else
+ {
+ if (_archiveAboveSize != -1 || _archiveEvery != ArchiveEveryMode.None)
+ {
+ if (NetworkWrites)
+ {
+ _appenderFactory = RetryingMultiProcessFileAppender.TheFactory;
+ }
+ else if (ConcurrentWrites)
+ {
+#if NETCF
+ _appenderFactory = RetryingMultiProcessFileAppender.TheFactory;
+#elif MONO
+ //
+ // mono on Windows uses mutexes, on Unix - special appender
+ //
+ if (PlatformDetector.IsCurrentOSCompatibleWith(RuntimeOS.Unix))
+ _appenderFactory = UnixMultiProcessFileAppender.TheFactory;
+ else
+ _appenderFactory = MutexMultiProcessFileAppender.TheFactory;
+#else
+ _appenderFactory = MutexMultiProcessFileAppender.TheFactory;
+#endif
+ }
+ else
+ {
+ _appenderFactory = CountingSingleProcessFileAppender.TheFactory;
+ }
+ }
+ else
+ {
+ if (NetworkWrites)
+ {
+ _appenderFactory = RetryingMultiProcessFileAppender.TheFactory;
+ }
+ else if (ConcurrentWrites)
+ {
+#if NETCF
+ _appenderFactory = RetryingMultiProcessFileAppender.TheFactory;
+#elif MONO
+ //
+ // mono on Windows uses mutexes, on Unix - special appender
+ //
+ if (PlatformDetector.IsCurrentOSCompatibleWith(RuntimeOS.Unix))
+ _appenderFactory = UnixMultiProcessFileAppender.TheFactory;
+ else
+ _appenderFactory = MutexMultiProcessFileAppender.TheFactory;
+#else
+ _appenderFactory = MutexMultiProcessFileAppender.TheFactory;
+#endif
+ }
+ else
+ {
+ _appenderFactory = SingleProcessFileAppender.TheFactory;
+ }
+ }
+ }
+
+ _recentAppenders = new BaseFileAppender[OpenFileCacheSize];
+
+ if ((OpenFileCacheSize > 0 || EnableFileDelete) && OpenFileCacheTimeout > 0)
+ {
+ _autoClosingTimer = new Timer(new TimerCallback(this.AutoClosingTimerCallback), null, OpenFileCacheTimeout * 1000, OpenFileCacheTimeout * 1000);
+ }
+
+ // Console.Error.WriteLine("Name: {0} Factory: {1}", this.Name, _appenderFactory.GetType().FullName);
+ }
+
+ private void AutoClosingTimerCallback(object state)
+ {
+ lock (this)
+ {
+ try
+ {
+ DateTime timeToKill = DateTime.Now.AddSeconds(-OpenFileCacheTimeout);
+ for (int i = 0; i < _recentAppenders.Length; ++i)
+ {
+ if (_recentAppenders[i] == null)
+ break;
+
+ if (_recentAppenders[i].OpenTime < timeToKill)
+ {
+ for (int j = i; j < _recentAppenders.Length; ++j)
+ {
+ if (_recentAppenders[j] == null)
+ break;
+ _recentAppenders[j].Close();
+ _recentAppenders[j] = null;
+ }
+ break;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Warn("Exception in AutoClosingTimerCallback: {0}", ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Modifies the specified byte array before it gets sent to a file.
+ /// </summary>
+ /// <param name="bytes">The byte array</param>
+ /// <returns>The modified byte array. The function can do the modification in-place.</returns>
+ protected virtual byte[] TransformBytes(byte[] bytes)
+ {
+ return bytes;
+ }
+
+ private void WriteToFile(string fileName, byte[] bytes, bool justData)
+ {
+ if (ReplaceFileContentsOnEachWrite)
+ {
+ using (FileStream fs = File.Create(fileName))
+ {
+ byte[] headerBytes = GetHeaderBytes();
+ byte[] footerBytes = GetFooterBytes();
+
+ if (headerBytes != null)
+ fs.Write(headerBytes, 0, headerBytes.Length);
+ fs.Write(bytes, 0, bytes.Length);
+ if (footerBytes != null)
+ fs.Write(footerBytes, 0, footerBytes.Length);
+ }
+ return;
+ }
+
+ bool writeHeader = false;
+
+ if (!justData)
+ {
+ if (!_initializedFiles.Contains(fileName))
+ {
+ if (DeleteOldFileOnStartup)
+ {
+ try
+ {
+ File.Delete(fileName);
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Warn("Unable to delete old log file '{0}': {1}", fileName, ex);
+ }
+ }
+ _initializedFiles[fileName] = DateTime.Now;
+ _initializedFilesCounter++;
+ writeHeader = true;
+
+ if (_initializedFilesCounter >= 100)
+ {
+ _initializedFilesCounter = 0;
+ CleanupInitializedFiles();
+ }
+ }
+ _initializedFiles[fileName] = DateTime.Now;
+ }
+
+ //
+ // BaseFileAppender.Write is the most expensive operation here
+ // so the in-memory data structure doesn't have to be
+ // very sophisticated. It's a table-based LRU, where we move
+ // the used element to become the first one.
+ // The number of items is usually very limited so the
+ // performance should be equivalent to the one of the hashtable.
+ //
+
+ BaseFileAppender appenderToWrite = null;
+ int freeSpot = _recentAppenders.Length - 1;
+
+ for (int i = 0; i < _recentAppenders.Length; ++i)
+ {
+ if (_recentAppenders[i] == null)
+ {
+ freeSpot = i;
+ break;
+ }
+
+ if (_recentAppenders[i].FileName == fileName)
+ {
+ // found it, move it to the first place on the list
+ // (MRU)
+
+ // file open has a chance of failure
+ // if it fails in the constructor, we won't modify any data structures
+
+ BaseFileAppender app = _recentAppenders[i];
+ for (int j = i; j > 0; --j)
+ _recentAppenders[j] = _recentAppenders[j - 1];
+ _recentAppenders[0] = app;
+ appenderToWrite = app;
+ break;
+ }
+ }
+
+ if (appenderToWrite == null)
+ {
+ BaseFileAppender newAppender = _appenderFactory.Open(fileName, this);
+
+ if (_recentAppenders[freeSpot] != null)
+ {
+ _recentAppenders[freeSpot].Close();
+ _recentAppenders[freeSpot] = null;
+ }
+
+ for (int j = freeSpot; j > 0; --j)
+ {
+ _recentAppenders[j] = _recentAppenders[j - 1];
+ }
+
+ _recentAppenders[0] = newAppender;
+ appenderToWrite = newAppender;
+ }
+
+ if (writeHeader && !justData)
+ {
+ byte[] headerBytes = GetHeaderBytes();
+ if (headerBytes != null)
+ {
+ appenderToWrite.Write(headerBytes);
+ }
+ }
+
+ appenderToWrite.Write(bytes);
+ }
+
+ private byte[] GetHeaderBytes()
+ {
+ if (CompiledHeader == null)
+ return null;
+
+ string renderedText = CompiledHeader.GetFormattedMessage(LogEventInfo.CreateNullEvent()) + NewLineChars;
+ return TransformBytes(_encoding.GetBytes(renderedText));
+ }
+
+ private byte[] GetFooterBytes()
+ {
+ if (CompiledFooter == null)
+ return null;
+
+ string renderedText = CompiledFooter.GetFormattedMessage(LogEventInfo.CreateNullEvent()) + NewLineChars;
+ return TransformBytes(_encoding.GetBytes(renderedText));
+ }
+
+ /// <summary>
+ /// Removes records of initialized files that have not been
+ /// accessed in the last two days.
+ /// </summary>
+ /// <remarks>
+ /// Files are marked 'initialized' for the purpose of writing footers when the logging finishes.
+ /// </remarks>
+ public void CleanupInitializedFiles()
+ {
+ CleanupInitializedFiles(DateTime.Now.AddDays(-2));
+ }
+
+ /// <summary>
+ /// Removes records of initialized files that have not been
+ /// accessed after the specified date.
+ /// </summary>
+ /// <remarks>
+ /// Files are marked 'initialized' for the purpose of writing footers when the logging finishes.
+ /// </remarks>
+ public void CleanupInitializedFiles(DateTime cleanupThreshold)
+ {
+ // clean up files that are two days old
+
+ ArrayList filesToUninitialize = new ArrayList();
+
+ foreach (DictionaryEntry de in _initializedFiles)
+ {
+ string fileName = (string)de.Key;
+ DateTime lastWriteTime = (DateTime)de.Value;
+ if (lastWriteTime < cleanupThreshold)
+ {
+ filesToUninitialize.Add(fileName);
+ }
+ }
+
+ foreach (string fileName in filesToUninitialize)
+ {
+ WriteFooterAndUninitialize(fileName);
+ }
+ }
+
+ private void WriteFooterAndUninitialize(string fileName)
+ {
+ byte[] footerBytes = GetFooterBytes();
+ if (footerBytes != null)
+ {
+ if (File.Exists(fileName))
+ {
+ WriteToFile(fileName, footerBytes, true);
+ }
+ }
+ _initializedFiles.Remove(fileName);
+ }
+
+ /// <summary>
+ /// Flushes all pending file operations.
+ /// </summary>
+ /// <param name="timeout">The timeout</param>
+ /// <remarks>
+ /// The timeout parameter is ignored, because file APIs don't provide
+ /// the needed functionality.
+ /// </remarks>
+ public override void Flush(TimeSpan timeout)
+ {
+ for (int i = 0; i < _recentAppenders.Length; ++i)
+ {
+ if (_recentAppenders[i] == null)
+ break;
+ _recentAppenders[i].Flush();
+ }
+ }
+
+ /// <summary>
+ /// Closes the file(s) opened for writing.
+ /// </summary>
+ protected internal override void Close()
+ {
+ base.Close();
+
+ lock (this)
+ {
+ foreach (string fileName in new ArrayList(_initializedFiles.Keys))
+ {
+ WriteFooterAndUninitialize(fileName);
+ }
+
+ if (_autoClosingTimer != null)
+ {
+ _autoClosingTimer.Change(Timeout.Infinite, Timeout.Infinite);
+ _autoClosingTimer.Dispose();
+ _autoClosingTimer = null;
+ }
+ }
+
+ for (int i = 0; i < _recentAppenders.Length; ++i)
+ {
+ if (_recentAppenders[i] == null)
+ break;
+ _recentAppenders[i].Close();
+ _recentAppenders[i] = null;
+ }
+ }
+
+ private bool GetFileInfo(string fileName, out DateTime lastWriteTime, out long fileLength)
+ {
+ for (int i = 0; i < _recentAppenders.Length; ++i)
+ {
+ if (_recentAppenders[i] == null)
+ break;
+ if (_recentAppenders[i].FileName == fileName)
+ {
+ _recentAppenders[i].GetFileInfo(out lastWriteTime, out fileLength);
+ return true;
+ }
+ }
+
+ FileInfo fi = new FileInfo(fileName);
+ if (fi.Exists)
+ {
+ fileLength = fi.Length;
+ lastWriteTime = fi.LastWriteTime;
+ return true;
+ }
+ else
+ {
+ fileLength = -1;
+ lastWriteTime = DateTime.MinValue;
+ return false;
+ }
+ }
+
+ private void InvalidateCacheItem(string fileName)
+ {
+ for (int i = 0; i < _recentAppenders.Length; ++i)
+ {
+ if (_recentAppenders[i] == null)
+ break;
+ if (_recentAppenders[i].FileName == fileName)
+ {
+ _recentAppenders[i].Close();
+ for (int j = i; j < _recentAppenders.Length - 1; ++j)
+ _recentAppenders[j] = _recentAppenders[j + 1];
+ _recentAppenders[_recentAppenders.Length - 1] = null;
+ break;
+ }
+ }
+ }
+
+ class LogEventComparer : IComparer
+ {
+ private FileTarget _fileTarget;
+
+ public LogEventComparer(FileTarget fileTarget)
+ {
+ _fileTarget = fileTarget;
+ }
+
+ public int Compare(object x, object y)
+ {
+ LogEventInfo le1 = (LogEventInfo)x;
+ LogEventInfo le2 = (LogEventInfo)y;
+
+ string filename1 = _fileTarget._fileNameLayout.GetFormattedMessage(le1);
+ string filename2 = _fileTarget._fileNameLayout.GetFormattedMessage(le2);
+
+ int val = String.CompareOrdinal(filename1, filename2);
+ if (val != 0)
+ return val;
+
+ if (le1.SequenceID < le2.SequenceID)
+ return -1;
+ if (le1.SequenceID > le2.SequenceID)
+ return 1;
+ return 0;
+ }
+ }
+ }
+}
diff --git a/src/NLog/Targets/FormControl.cs b/src/NLog/Targets/FormControl.cs
new file mode 100644
index 0000000..1c71abc
--- /dev/null
+++ b/src/NLog/Targets/FormControl.cs
@@ -0,0 +1,147 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF && !MONO
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Text;
+
+using System.Windows.Forms;
+
+using NLog.Config;
+using NLog.Internal;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Log text to Windows.Forms.Control.Text property control of specified Name
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/FormControl/NLog.config" />
+ /// <p>
+ /// The result is:
+ /// </p>
+ /// <img src="examples/targets/Screenshots/FormControl/FormControl.gif" />
+ /// <p>
+ /// To set up the log target programmatically similar to above use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/FormControl/Form1.cs" />,
+ /// </example>
+ [Target("FormControl")]
+ [SupportedRuntime(Framework=RuntimeFramework.DotNetFramework, MinRuntimeVersion="1.1")]
+ public sealed class FormControlTarget : TargetWithLayout
+ {
+ private string _controlName;
+ private bool _append = true;
+ private string _formName;
+
+ /// <summary>
+ /// Name of control to which Nlog will log
+ /// </summary>
+ [RequiredParameter]
+ public string ControlName
+ {
+ get { return _controlName; }
+ set { _controlName = value; }
+ }
+
+ /// <summary>
+ /// Setting to tell to append or overwrite the Text property of control
+ /// </summary>
+ public bool Append
+ {
+ get { return _append; }
+ set { _append = value; }
+ }
+
+ /// <summary>
+ /// Name of the Form on which the control is located.
+ /// </summary>
+ public string FormName
+ {
+ get { return _formName; }
+ set { _formName = value; }
+ }
+
+ /// <summary>
+ /// Log message to control
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ string logMessage = CompiledLayout.GetFormattedMessage(logEvent);
+
+ FindControlAndSendTheMessage(logMessage);
+ }
+
+ private void FindControlAndSendTheMessage(string logMessage)
+ {
+ Form form = null;
+
+ if (Form.ActiveForm != null)
+ form = Form.ActiveForm;
+
+#if DOTNET_2_0
+ if (Application.OpenForms[FormName] != null)
+ form = Application.OpenForms[FormName];
+#endif
+ if (form == null)
+ return;
+
+ Control ctrl = FormHelper.FindControl(ControlName, form);
+
+ if (ctrl == null)
+ return;
+
+ ctrl.Invoke(new DelSendTheMessageToFormControl(SendTheMessageToFormControl), new object[] { ctrl, logMessage });
+ }
+
+ private delegate void DelSendTheMessageToFormControl(Control ctrl, string logMessage);
+
+ private void SendTheMessageToFormControl(Control ctrl, string logMessage)
+ {
+ if (Append)
+ ctrl.Text += logMessage;
+ else
+ ctrl.Text = logMessage;
+ }
+ }
+}
+#endif
diff --git a/src/NLog/Targets/Mail.cs b/src/NLog/Targets/Mail.cs
new file mode 100644
index 0000000..baa1cd7
--- /dev/null
+++ b/src/NLog/Targets/Mail.cs
@@ -0,0 +1,463 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Text;
+using System.Diagnostics;
+using System.Reflection;
+
+#if NET_2_API
+using System.Net;
+using System.Net.Mail;
+#else
+using System.Web.Mail;
+#endif
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Sends logging messages by email using SMTP protocol.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/Mail/Simple/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/Mail/Simple/Example.cs" />
+ /// <p>
+ /// Mail target works best when used with BufferingWrapper target
+ /// which lets you send multiple logging messages in single mail
+ /// </p>
+ /// <p>
+ /// To set up the buffered mail target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/Mail/Buffered/NLog.config" />
+ /// <p>
+ /// To set up the buffered mail target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/Mail/Buffered/Example.cs" />
+ /// </example>
+ [Target("Mail",IgnoresLayout=true)]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class MailTarget: TargetWithLayoutHeaderAndFooter
+ {
+ /// <summary>
+ /// SMTP authentication modes.
+ /// </summary>
+ public enum SmtpAuthenticationMode
+ {
+ /// <summary>
+ /// No authentication.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// Basic - username and password
+ /// </summary>
+ Basic,
+
+ /// <summary>
+ /// NTLM Authentication
+ /// </summary>
+ Ntlm,
+ }
+
+ private Layout _from;
+ private Layout _to;
+ private Layout _cc;
+ private Layout _bcc;
+ private Layout _subject = new Layout("Message from NLog on ${machinename}");
+ private Encoding _encoding = System.Text.Encoding.UTF8;
+ private string _smtpServer;
+ private string _smtpUsername;
+ private string _smtpPassword;
+ private SmtpAuthenticationMode _smtpAuthentication = SmtpAuthenticationMode.None;
+ private int _smtpPort = 25;
+ private bool _isHtml = false;
+ private bool _newLines = false;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="MailTarget"/>.
+ /// </summary>
+ public MailTarget()
+ {
+ Body = "${message}${newline}";
+ }
+
+ /// <summary>
+ /// Sender's email address (e.g. joe at domain.com)
+ /// </summary>
+ public string From
+ {
+ get { return _from.Text; }
+ set { _from = new Layout(value); }
+ }
+
+ /// <summary>
+ /// Recipients' email addresses separated by semicolons (e.g. john at domain.com;jane at domain.com)
+ /// </summary>
+ public string To
+ {
+ get { return _to.Text; }
+ set { _to = new Layout(value); }
+ }
+
+ /// <summary>
+ /// CC email addresses separated by semicolons (e.g. john at domain.com;jane at domain.com)
+ /// </summary>
+ public string CC
+ {
+ get { return _cc.Text; }
+ set { _cc = new Layout(value); }
+ }
+
+ /// <summary>
+ /// BCC email addresses separated by semicolons (e.g. john at domain.com;jane at domain.com)
+ /// </summary>
+ public string BCC
+ {
+ get { return _bcc.Text; }
+ set { _bcc = new Layout(value); }
+ }
+
+ /// <summary>
+ /// Whether to add new lines between log entries.
+ /// </summary>
+ /// <value><c>true</c> if new lines should be added; otherwise, <c>false</c>.</value>
+ public bool AddNewLines
+ {
+ get { return _newLines; }
+ set { _newLines = value; }
+ }
+
+ /// <summary>
+ /// Mail subject.
+ /// </summary>
+ [System.ComponentModel.DefaultValue("Message from NLog on ${machinename}")]
+ public string Subject
+ {
+ get { return _subject.Text; }
+ set { _subject = new Layout(value); }
+ }
+
+ /// <summary>
+ /// Mail message body (repeated for each log message send in one mail)
+ /// </summary>
+ [System.ComponentModel.DefaultValue("${message}")]
+ public string Body
+ {
+ get { return base.Layout; }
+ set { base.Layout = value; }
+ }
+
+ /// <summary>
+ /// Encoding to be used for sending e-mail.
+ /// </summary>
+ [System.ComponentModel.DefaultValue("UTF8")]
+ public string Encoding
+ {
+ get { return _encoding.WebName; }
+ set { _encoding = System.Text.Encoding.GetEncoding(value); }
+ }
+
+ /// <summary>
+ /// Send message as HTML instead of plain text.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool HTML
+ {
+ get { return _isHtml; }
+ set { _isHtml = value; }
+ }
+
+ /// <summary>
+ /// SMTP Server to be used for sending.
+ /// </summary>
+ public string SmtpServer
+ {
+ get { return _smtpServer; }
+ set { _smtpServer = value; }
+ }
+
+ /// <summary>
+ /// SMTP Authentication mode.
+ /// </summary>
+ [System.ComponentModel.DefaultValue("None")]
+ public SmtpAuthenticationMode SmtpAuthentication
+ {
+ get { return _smtpAuthentication; }
+ set
+ {
+#if !NET_2_API
+ AssertFieldsSupport("SmtpAuthentication");
+#endif
+ _smtpAuthentication = value;
+ }
+ }
+
+ /// <summary>
+ /// The username used to connect to SMTP server (used when SmtpAuthentication is set to "basic").
+ /// </summary>
+ public string SmtpUsername
+ {
+ get { return _smtpUsername; }
+ set
+ {
+#if !NET_2_API
+ AssertFieldsSupport("SMTPUsername");
+#endif
+ _smtpUsername = value;
+ }
+ }
+
+ /// <summary>
+ /// The password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic").
+ /// </summary>
+ public string SmtpPassword
+ {
+ get { return _smtpPassword; }
+ set
+ {
+#if !NET_2_API
+ AssertFieldsSupport("SMTPPassword");
+#endif
+ _smtpPassword = value;
+ }
+ }
+
+ /// <summary>
+ /// The port that SMTP Server is listening on.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(25)]
+ public int SmtpPort
+ {
+ get { return _smtpPort; }
+ set
+ {
+#if !NET_2_API
+ if (value != 25)
+ AssertFieldsSupport("SmtpPort");
+#endif
+ _smtpPort = value;
+ }
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ base.PopulateLayouts (layouts);
+ if (_from != null) _from.PopulateLayouts(layouts);
+ if (_to != null) _to.PopulateLayouts(layouts);
+ if (_cc != null) _cc.PopulateLayouts(layouts);
+ if (_bcc != null) _bcc.PopulateLayouts(layouts);
+ if (_subject != null) _subject.PopulateLayouts(layouts);
+ }
+
+ /// <summary>
+ /// Renders the logging event message and adds it to the internal ArrayList of log messages.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ this.Write(new LogEventInfo[1] { logEvent });
+ }
+
+ /// <summary>
+ /// Renders an array logging events.
+ /// </summary>
+ /// <param name="events">Array of logging events.</param>
+ protected internal override void Write(LogEventInfo[] events)
+ {
+ if (events == null)
+ return;
+ if (events.Length == 0)
+ return;
+
+ if (_from == null || _to == null || _subject == null)
+ return;
+
+ LogEventInfo lastEvent = events[events.Length - 1];
+ string bodyText;
+
+ // unbuffered case, create a local buffer, append header, body and footer
+ StringBuilder bodyBuffer = new StringBuilder();
+ if (CompiledHeader != null)
+ {
+ bodyBuffer.Append(CompiledHeader.GetFormattedMessage(lastEvent));
+ if (AddNewLines)
+ bodyBuffer.Append("\n");
+ }
+ for (int i = 0; i < events.Length; ++i)
+ {
+ bodyBuffer.Append(CompiledLayout.GetFormattedMessage(events[i]));
+ if (AddNewLines)
+ bodyBuffer.Append("\n");
+ }
+ if (CompiledFooter != null)
+ {
+ bodyBuffer.Append(CompiledFooter.GetFormattedMessage(lastEvent));
+ if (AddNewLines)
+ bodyBuffer.Append("\n");
+ }
+
+ bodyText = bodyBuffer.ToString();
+
+ MailMessage msg = new MailMessage();
+ SetupMailMessage(msg, lastEvent);
+ msg.Body = bodyText;
+ SendMessage(msg);
+ }
+
+ private void SetupMailMessage(MailMessage msg, LogEventInfo logEvent)
+ {
+#if NET_2_API
+ msg.From = new MailAddress(_from.GetFormattedMessage(logEvent));
+ foreach (string mail in _to.GetFormattedMessage(logEvent).Split(';'))
+ {
+ msg.To.Add(mail);
+ }
+ if (_bcc != null)
+ {
+ foreach (string mail in _bcc.GetFormattedMessage(logEvent).Split(';'))
+ {
+ msg.Bcc.Add(mail);
+ }
+ }
+
+ if (_cc != null)
+ {
+ foreach (string mail in _cc.GetFormattedMessage(logEvent).Split(';'))
+ {
+ msg.CC.Add(mail);
+ }
+ }
+ msg.Subject = _subject.GetFormattedMessage(logEvent);
+ msg.BodyEncoding = System.Text.Encoding.UTF8;
+ msg.IsBodyHtml = HTML;
+ msg.Priority = MailPriority.Normal;
+#else
+
+ msg.From = _from.GetFormattedMessage(logEvent);
+ msg.To = _to.GetFormattedMessage(logEvent);
+ if (_bcc != null)
+ msg.Bcc = _bcc.GetFormattedMessage(logEvent);
+
+ if (_cc != null)
+ msg.Cc = _cc.GetFormattedMessage(logEvent);
+ msg.Subject = _subject.GetFormattedMessage(logEvent);
+ msg.BodyEncoding = System.Text.Encoding.UTF8;
+ msg.BodyFormat = HTML ? MailFormat.Html : MailFormat.Text;
+ msg.Priority = MailPriority.Normal;
+#endif
+ }
+
+ private void SendMessage(MailMessage msg)
+ {
+#if NET_2_API
+ SmtpClient client = new SmtpClient(SmtpServer, SmtpPort);
+#if !MONO
+ // the credentials API is broken in Mono as of 2006-05-05
+
+ if (SmtpAuthentication == SmtpAuthenticationMode.Ntlm)
+ client.Credentials = CredentialCache.DefaultNetworkCredentials;
+ else if (SmtpAuthentication == SmtpAuthenticationMode.Basic)
+ client.Credentials = new NetworkCredential(SmtpUsername, SmtpPassword);
+#endif
+ Internal.InternalLogger.Debug("Sending mail to {0} using {1}", msg.To, _smtpServer);
+ client.Send(msg);
+#else
+ IDictionary fields = GetFieldsDictionary(msg);
+ if (fields != null)
+ {
+ if (SmtpPort != 25)
+ {
+ fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", SmtpPort);
+ }
+ if (SmtpAuthentication == SmtpAuthenticationMode.Basic)
+ {
+ fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1");
+ fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", SmtpUsername);
+ fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", SmtpPassword);
+ }
+ if (SmtpAuthentication == SmtpAuthenticationMode.Ntlm)
+ {
+ fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "2");
+ }
+ }
+ SmtpMail.SmtpServer = _smtpServer;
+ Internal.InternalLogger.Debug("Sending mail to {0} using {1}", msg.To, _smtpServer);
+
+ SmtpMail.Send(msg);
+#endif
+ }
+
+#if !NET_2_API
+ // .NET 1.0 doesn't support "MailMessage.Fields". We want to be portable so
+ // we detect this at runtime.
+
+ private PropertyInfo _fieldsProperty = typeof(MailMessage).GetProperty("Fields");
+
+ private void AssertFieldsSupport(string fieldName)
+ {
+ if (_fieldsProperty == null)
+ throw new ArgumentException("Parameter " + fieldName + " isn't supported on this runtime version.");
+ }
+
+ private IDictionary GetFieldsDictionary(MailMessage m)
+ {
+ if (_fieldsProperty == null)
+ return null;
+
+ return (IDictionary)_fieldsProperty.GetValue(m, null);
+ }
+#endif
+ }
+}
+
+#endif
diff --git a/src/NLog/Targets/Memory.cs b/src/NLog/Targets/Memory.cs
new file mode 100644
index 0000000..8c92330
--- /dev/null
+++ b/src/NLog/Targets/Memory.cs
@@ -0,0 +1,81 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Writes logging messages to an ArrayList in memory for programmatic retrieval.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/Memory/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/Memory/Simple/Example.cs" />
+ /// </example>
+ [Target("Memory")]
+ public sealed class MemoryTarget: TargetWithLayout
+ {
+ private ArrayList _logs = new ArrayList();
+
+ /// <summary>
+ /// Renders the logging event message and adds it to the internal ArrayList of log messages.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ _logs.Add(CompiledLayout.GetFormattedMessage(logEvent));
+ }
+
+ /// <summary>
+ /// Returns the list of logs gathered in the <see cref="MemoryTarget"/>.
+ /// </summary>
+ public ArrayList Logs
+ {
+ get { return _logs; }
+ }
+ }
+}
diff --git a/src/NLog/Targets/MessageBox.cs b/src/NLog/Targets/MessageBox.cs
new file mode 100644
index 0000000..c81e018
--- /dev/null
+++ b/src/NLog/Targets/MessageBox.cs
@@ -0,0 +1,132 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Text;
+
+using System.Windows.Forms;
+
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Pops up logging messages as message boxes.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/MessageBox/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// The result is a message box:
+ /// </p>
+ /// <img src="examples/targets/Screenshots/MessageBox/MessageBoxTarget.gif" />
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/MessageBox/Simple/Example.cs" />
+ /// </example>
+ [Target("MessageBox")]
+ public sealed class MessageBoxTarget: TargetWithLayout
+ {
+ private Layout _caption = null;
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="MessageBoxTarget"/>.
+ /// </summary>
+ public MessageBoxTarget()
+ {
+ Caption = "NLog";
+ }
+
+ /// <summary>
+ /// Message box title.
+ /// </summary>
+ [AcceptsLayout]
+ public string Caption
+ {
+ get { return _caption.Text; }
+ set { _caption = new Layout(value); }
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ base.PopulateLayouts (layouts);
+ _caption.PopulateLayouts(layouts);
+ }
+
+ /// <summary>
+ /// Displays the message box with the log message and caption specified in the Caption
+ /// parameter.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ MessageBox.Show(CompiledLayout.GetFormattedMessage(logEvent), _caption.GetFormattedMessage(logEvent));
+ }
+
+ /// <summary>
+ /// Displays the message box with the array of rendered logs messages and caption specified in the Caption
+ /// parameter.
+ /// </summary>
+ /// <param name="logEvents">The array of logging events.</param>
+ protected internal override void Write(LogEventInfo[] logEvents)
+ {
+ if (logEvents.Length == 0)
+ return;
+
+ StringBuilder sb = new StringBuilder();
+ LogEventInfo lastLogEvent = logEvents[logEvents.Length - 1];
+ foreach (LogEventInfo ev in logEvents)
+ {
+ sb.Append(CompiledLayout.GetFormattedMessage(ev));
+ sb.Append("\n");
+ }
+
+ MessageBox.Show(sb.ToString(), _caption.GetFormattedMessage(lastLogEvent));
+ }
+ }
+}
diff --git a/src/NLog/Targets/MethodCall.cs b/src/NLog/Targets/MethodCall.cs
new file mode 100644
index 0000000..3a5cfc8
--- /dev/null
+++ b/src/NLog/Targets/MethodCall.cs
@@ -0,0 +1,127 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Reflection;
+using System.Globalization;
+
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Calls the specified static method on each logging message and passes contextual parameters to it.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/MethodCall/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/MethodCall/Simple/Example.cs" />
+ /// </example>
+ [Target("MethodCall")]
+ public sealed class MethodCallTarget: MethodCallTargetBase
+ {
+ private string _className = null;
+ private MethodInfo _methodInfo = null;
+ private string _methodName = null;
+
+ /// <summary>
+ /// The class name.
+ /// </summary>
+ public string ClassName
+ {
+ get { return _className; }
+ set
+ {
+ _className = value;
+ UpdateMethodInfo();
+ }
+ }
+
+ /// <summary>
+ /// The method name. The method must be public and static.
+ /// </summary>
+ public string MethodName
+ {
+ get { return _methodName; }
+ set
+ {
+ _methodName = value;
+ UpdateMethodInfo();
+ }
+ }
+
+ private MethodInfo Method
+ {
+ get { return _methodInfo; }
+ set { _methodInfo = value; }
+ }
+
+ private void UpdateMethodInfo()
+ {
+ if (ClassName != null && MethodName != null)
+ {
+ Type targetType = Type.GetType(ClassName);
+ Method = targetType.GetMethod(MethodName);
+ }
+ else
+ {
+ Method = null;
+ }
+ }
+
+ /// <summary>
+ /// Calls the specified Method.
+ /// </summary>
+ /// <param name="parameters">Method parameters.</param>
+ protected override void DoInvoke(object[]parameters)
+ {
+ if (Method != null)
+ {
+ Method.Invoke(null, parameters);
+ }
+ }
+ }
+}
diff --git a/src/NLog/Targets/MethodCallParameter.cs b/src/NLog/Targets/MethodCallParameter.cs
new file mode 100644
index 0000000..00ae1a6
--- /dev/null
+++ b/src/NLog/Targets/MethodCallParameter.cs
@@ -0,0 +1,137 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Reflection;
+using System.Globalization;
+
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// A parameter to MethodCall.
+ /// </summary>
+ public class MethodCallParameter
+ {
+ private Type _type;
+ private Layout _compiledlayout;
+ private string _name;
+
+ /// <summary>
+ /// Constructs a new instance of <see cref="MethodCallParameter"/> and sets
+ /// the type to String.
+ /// </summary>
+ public MethodCallParameter()
+ {
+ _type = typeof(string);
+ }
+
+ /// <summary>
+ /// Constructs a new instance of <see cref="MethodCallParameter"/>, sets
+ /// the type to String and initializes the Layout property.
+ /// </summary>
+ public MethodCallParameter(string layout)
+ {
+ _type = typeof(string);
+ Layout = layout;
+ }
+
+ /// <summary>
+ /// Constructs a new instance of <see cref="MethodCallParameter"/>, sets
+ /// the type to String and initializes the Name and Layout properties.
+ /// </summary>
+ public MethodCallParameter(string name, string layout)
+ {
+ _type = typeof(string);
+ Name = name;
+ Layout = layout;
+ }
+
+ /// <summary>
+ /// Constructs a new instance of <see cref="MethodCallParameter"/>, sets
+ /// the type to String and initializes the Name, Layout and Type properties.
+ /// </summary>
+ public MethodCallParameter(string name, Type type, string layout)
+ {
+ _type = type;
+ Name = name;
+ Layout = layout;
+ }
+
+ /// <summary>
+ /// The name of the parameter.
+ /// </summary>
+ public string Name
+ {
+ get { return _name; }
+ set { _name = value; }
+ }
+
+ /// <summary>
+ /// The type of the parameter.
+ /// </summary>
+ public string Type
+ {
+ get { return _type.FullName; }
+ set { _type = System.Type.GetType(value); }
+ }
+
+ /// <summary>
+ /// The layout that should be use to calcuate the value for the parameter.
+ /// </summary>
+ [RequiredParameter]
+ public string Layout
+ {
+ get { return _compiledlayout.Text; }
+ set { _compiledlayout = new Layout(value); }
+ }
+
+ /// <summary>
+ /// The compiled layout that should be use to calcuate the value for the parameter.
+ /// </summary>
+ public Layout CompiledLayout
+ {
+ get { return _compiledlayout; }
+ set { _compiledlayout = value; }
+ }
+
+ internal object GetValue(LogEventInfo logEvent)
+ {
+ return Convert.ChangeType(CompiledLayout.GetFormattedMessage(logEvent), _type, CultureInfo.InvariantCulture);
+ }
+ }
+}
diff --git a/src/NLog/Targets/MethodCallParameterCollection.cs b/src/NLog/Targets/MethodCallParameterCollection.cs
new file mode 100644
index 0000000..0026af6
--- /dev/null
+++ b/src/NLog/Targets/MethodCallParameterCollection.cs
@@ -0,0 +1,248 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Reflection;
+using System.Globalization;
+
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A collection of elements of type MethodCallParameter
+ /// </summary>
+ public class MethodCallParameterCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the MethodCallParameterCollection class.
+ /// </summary>
+ public MethodCallParameterCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the MethodCallParameterCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new MethodCallParameterCollection.
+ /// </param>
+ public MethodCallParameterCollection(MethodCallParameter[]items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the MethodCallParameterCollection class, containing elements
+ /// copied from another instance of MethodCallParameterCollection
+ /// </summary>
+ /// <param name="items">
+ /// The MethodCallParameterCollection whose elements are to be added to the new MethodCallParameterCollection.
+ /// </param>
+ public MethodCallParameterCollection(MethodCallParameterCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this MethodCallParameterCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this MethodCallParameterCollection.
+ /// </param>
+ public virtual void AddRange(MethodCallParameter[]items)
+ {
+ foreach (MethodCallParameter item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another MethodCallParameterCollection to the end of this MethodCallParameterCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The MethodCallParameterCollection whose elements are to be added to the end of this MethodCallParameterCollection.
+ /// </param>
+ public virtual void AddRange(MethodCallParameterCollection items)
+ {
+ foreach (MethodCallParameter item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type MethodCallParameter to the end of this MethodCallParameterCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The MethodCallParameter to be added to the end of this MethodCallParameterCollection.
+ /// </param>
+ public virtual void Add(MethodCallParameter value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic MethodCallParameter value is in this MethodCallParameterCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The MethodCallParameter value to locate in this MethodCallParameterCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this MethodCallParameterCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(MethodCallParameter value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this MethodCallParameterCollection
+ /// </summary>
+ /// <param name="value">
+ /// The MethodCallParameter value to locate in the MethodCallParameterCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(MethodCallParameter value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the MethodCallParameterCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the MethodCallParameter is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The MethodCallParameter to insert.
+ /// </param>
+ public virtual void Insert(int index, MethodCallParameter value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the MethodCallParameter at the given index in this MethodCallParameterCollection.
+ /// </summary>
+ public virtual MethodCallParameter this[int index]
+ {
+ get { return (MethodCallParameter)this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific MethodCallParameter from this MethodCallParameterCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The MethodCallParameter value to remove from this MethodCallParameterCollection.
+ /// </param>
+ public virtual void Remove(MethodCallParameter value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by MethodCallParameterCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(MethodCallParameterCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public MethodCallParameter Current
+ {
+ get { return (MethodCallParameter)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (MethodCallParameter)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this MethodCallParameterCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual MethodCallParameterCollection.Enumerator GetEnumerator()
+ {
+ return new MethodCallParameterCollection.Enumerator(this);
+ }
+ }
+}
diff --git a/src/NLog/Targets/MethodCallTargetBase.cs b/src/NLog/Targets/MethodCallTargetBase.cs
new file mode 100644
index 0000000..272d6d7
--- /dev/null
+++ b/src/NLog/Targets/MethodCallTargetBase.cs
@@ -0,0 +1,94 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Reflection;
+using System.Globalization;
+
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// The base class for all targets which call methods (local or remote).
+ /// Manages parameters and type coercion.
+ /// </summary>
+ public abstract class MethodCallTargetBase: Target
+ {
+ private MethodCallParameterCollection _parameters = new MethodCallParameterCollection();
+
+ /// <summary>
+ /// Prepares an array of parameters to be passed based on the logging event and calls DoInvoke()
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ object[]parameters = new object[Parameters.Count];
+ for (int i = 0; i < parameters.Length; ++i)
+ {
+ parameters[i] = Parameters[i].GetValue(logEvent);
+ }
+
+ DoInvoke(parameters);
+ }
+
+ /// <summary>
+ /// Calls the target method. Must be implemented in concrete classes.
+ /// </summary>
+ /// <param name="parameters">Method call parameters</param>
+ protected abstract void DoInvoke(object[]parameters);
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ base.PopulateLayouts (layouts);
+ for (int i = 0; i < Parameters.Count; ++i)
+ Parameters[i].CompiledLayout.PopulateLayouts(layouts);
+ }
+
+ /// <summary>
+ /// Array of parameters to be passed.
+ /// </summary>
+ [ArrayParameter(typeof(MethodCallParameter), "parameter")]
+ public MethodCallParameterCollection Parameters
+ {
+ get { return _parameters; }
+ }
+ }
+}
diff --git a/src/NLog/Targets/NLogViewer.cs b/src/NLog/Targets/NLogViewer.cs
new file mode 100644
index 0000000..017fd68
--- /dev/null
+++ b/src/NLog/Targets/NLogViewer.cs
@@ -0,0 +1,195 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+
+using NLog.Config;
+using NLog.LayoutRenderers;
+using NLog.Layouts;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Sends logging messages to the remote instance of NLog Viewer.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/NLogViewer/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/NLogViewer/Simple/Example.cs" />
+ /// <p>
+ /// NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol
+ /// or you'll get TCP timeouts and your application will crawl.
+ /// Either switch to UDP transport or use <a href="target.AsyncWrapper.html">AsyncWrapper</a> target
+ /// so that your application threads will not be blocked by the timing-out connection attempts.
+ /// </p>
+ /// </example>
+ [Target("NLogViewer", IgnoresLayout=true)]
+ public class NLogViewerTarget: NetworkTarget
+ {
+ private NLogViewerParameterInfoCollection _parameters = new NLogViewerParameterInfoCollection();
+
+ private Log4JXmlEventLayoutRenderer Renderer
+ {
+ get { return Layout.Renderer; }
+ }
+
+ /// <summary>
+ /// An instance of <see cref="Log4JXmlEventLayout"/> that is used to format log messages.
+ /// </summary>
+ protected new Log4JXmlEventLayout Layout
+ {
+ get { return base.CompiledLayout as Log4JXmlEventLayout; }
+ set { CompiledLayout = value; }
+ }
+
+ /// <summary>
+ /// Include NLog-specific extensions to log4j schema.
+ /// </summary>
+ public bool IncludeNLogData
+ {
+ get { return Renderer.IncludeNLogData; }
+ set { Renderer.IncludeNLogData = value; }
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="NLogViewerTarget"/>
+ /// and initializes default property values.
+ /// </summary>
+ public NLogViewerTarget()
+ {
+ CompiledLayout = new Log4JXmlEventLayout();
+ Renderer.Parameters = _parameters;
+ NewLine = false;
+ }
+
+ /// <summary>
+ /// The AppInfo field. By default it's the friendly name of the current AppDomain.
+ /// </summary>
+ public string AppInfo
+ {
+ get { return Renderer.AppInfo; }
+ set { Renderer.AppInfo = value; }
+ }
+
+#if !NETCF
+ /// <summary>
+ /// Include call site (class and method name) in the information sent over the network.
+ /// </summary>
+ public bool IncludeCallSite
+ {
+ get { return Renderer.IncludeCallSite; }
+ set { Renderer.IncludeCallSite = value; }
+ }
+
+ /// <summary>
+ /// Include source info (file name and line number) in the information sent over the network.
+ /// </summary>
+ public bool IncludeSourceInfo
+ {
+ get { return Renderer.IncludeSourceInfo; }
+ set { Renderer.IncludeSourceInfo = value; }
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ base.PopulateLayouts (layouts);
+ for (int i = 0; i < Parameters.Count; ++i)
+ Parameters[i].CompiledLayout.PopulateLayouts(layouts);
+ }
+
+ /// <summary>
+ /// Returns the value indicating whether call site and/or source information should be gathered.
+ /// </summary>
+ /// <returns>2 - when IncludeSourceInfo is set, 1 when IncludeCallSite is set, 0 otherwise</returns>
+ protected internal override int NeedsStackTrace()
+ {
+ if (IncludeSourceInfo)
+ return 2;
+ if (IncludeCallSite)
+ return 1;
+
+ return base.NeedsStackTrace();
+ }
+#endif
+
+ /// <summary>
+ /// Include MDC dictionary in the information sent over the network.
+ /// </summary>
+ public bool IncludeMDC
+ {
+ get { return Renderer.IncludeMDC; }
+ set { Renderer.IncludeMDC = value; }
+ }
+
+ /// <summary>
+ /// Include NDC stack.
+ /// </summary>
+ public bool IncludeNDC
+ {
+ get { return Renderer.IncludeNDC; }
+ set { Renderer.IncludeNDC = value; }
+ }
+ /// <summary>
+ /// The collection of parameters. Each parameter contains a mapping
+ /// between NLog layout and a named parameter.
+ /// </summary>
+ [ArrayParameter(typeof(NLogViewerParameterInfo), "parameter")]
+ public NLogViewerParameterInfoCollection Parameters
+ {
+ get { return _parameters; }
+ }
+ }
+}
diff --git a/src/NLog/Targets/NLogViewerParameterInfo.cs b/src/NLog/Targets/NLogViewerParameterInfo.cs
new file mode 100644
index 0000000..7391ef6
--- /dev/null
+++ b/src/NLog/Targets/NLogViewerParameterInfo.cs
@@ -0,0 +1,89 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Diagnostics;
+using System.Reflection;
+using System.Data;
+using System.Collections;
+
+using NLog.Internal;
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Represents a parameter to a NLogViewer target.
+ /// </summary>
+ public class NLogViewerParameterInfo
+ {
+ /// <summary>ba
+ /// Creates a new instance of <see cref="NLogViewerParameterInfo"/>.
+ /// </summary>
+ public NLogViewerParameterInfo(){}
+
+ private Layout _compiledlayout;
+ private string _name;
+
+ /// <summary>
+ /// Viewer parameter name.
+ /// </summary>
+ [RequiredParameter]
+ public string Name
+ {
+ get { return _name; }
+ set { _name = value; }
+ }
+
+ /// <summary>
+ /// The layout that should be use to calcuate the value for the parameter.
+ /// </summary>
+ [RequiredParameter]
+ [AcceptsLayout]
+ public string Layout
+ {
+ get { return _compiledlayout.Text; }
+ set { _compiledlayout = new Layout(value); }
+ }
+
+ /// <summary>
+ /// The compiled representation of the Layout property.
+ /// </summary>
+ public Layout CompiledLayout
+ {
+ get { return _compiledlayout; }
+ set { _compiledlayout = value; }
+ }
+ }
+}
diff --git a/src/NLog/Targets/NLogViewerParameterInfoCollection.cs b/src/NLog/Targets/NLogViewerParameterInfoCollection.cs
new file mode 100644
index 0000000..59cb8a5
--- /dev/null
+++ b/src/NLog/Targets/NLogViewerParameterInfoCollection.cs
@@ -0,0 +1,249 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Diagnostics;
+using System.Reflection;
+using System.Data;
+using System.Collections;
+
+using NLog.Internal;
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A collection of elements of type NLogViewerParameterInfo
+ /// </summary>
+ public class NLogViewerParameterInfoCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the NLogViewerParameterInfoCollection class.
+ /// </summary>
+ public NLogViewerParameterInfoCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the NLogViewerParameterInfoCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new NLogViewerParameterInfoCollection.
+ /// </param>
+ public NLogViewerParameterInfoCollection(NLogViewerParameterInfo[]items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the NLogViewerParameterInfoCollection class, containing elements
+ /// copied from another instance of NLogViewerParameterInfoCollection
+ /// </summary>
+ /// <param name="items">
+ /// The NLogViewerParameterInfoCollection whose elements are to be added to the new NLogViewerParameterInfoCollection.
+ /// </param>
+ public NLogViewerParameterInfoCollection(NLogViewerParameterInfoCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this NLogViewerParameterInfoCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this NLogViewerParameterInfoCollection.
+ /// </param>
+ public virtual void AddRange(NLogViewerParameterInfo[]items)
+ {
+ foreach (NLogViewerParameterInfo item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another NLogViewerParameterInfoCollection to the end of this NLogViewerParameterInfoCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The NLogViewerParameterInfoCollection whose elements are to be added to the end of this NLogViewerParameterInfoCollection.
+ /// </param>
+ public virtual void AddRange(NLogViewerParameterInfoCollection items)
+ {
+ foreach (NLogViewerParameterInfo item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type NLogViewerParameterInfo to the end of this NLogViewerParameterInfoCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The NLogViewerParameterInfo to be added to the end of this NLogViewerParameterInfoCollection.
+ /// </param>
+ public virtual void Add(NLogViewerParameterInfo value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic NLogViewerParameterInfo value is in this NLogViewerParameterInfoCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The NLogViewerParameterInfo value to locate in this NLogViewerParameterInfoCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this NLogViewerParameterInfoCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(NLogViewerParameterInfo value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this NLogViewerParameterInfoCollection
+ /// </summary>
+ /// <param name="value">
+ /// The NLogViewerParameterInfo value to locate in the NLogViewerParameterInfoCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(NLogViewerParameterInfo value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the NLogViewerParameterInfoCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the NLogViewerParameterInfo is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The NLogViewerParameterInfo to insert.
+ /// </param>
+ public virtual void Insert(int index, NLogViewerParameterInfo value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the NLogViewerParameterInfo at the given index in this NLogViewerParameterInfoCollection.
+ /// </summary>
+ public virtual NLogViewerParameterInfo this[int index]
+ {
+ get { return (NLogViewerParameterInfo)this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific NLogViewerParameterInfo from this NLogViewerParameterInfoCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The NLogViewerParameterInfo value to remove from this NLogViewerParameterInfoCollection.
+ /// </param>
+ public virtual void Remove(NLogViewerParameterInfo value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by NLogViewerParameterInfoCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(NLogViewerParameterInfoCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public NLogViewerParameterInfo Current
+ {
+ get { return (NLogViewerParameterInfo)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (NLogViewerParameterInfo)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this NLogViewerParameterInfoCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual NLogViewerParameterInfoCollection.Enumerator GetEnumerator()
+ {
+ return new NLogViewerParameterInfoCollection.Enumerator(this);
+ }
+ }
+}
diff --git a/src/NLog/Targets/Network.cs b/src/NLog/Targets/Network.cs
new file mode 100644
index 0000000..653e67d
--- /dev/null
+++ b/src/NLog/Targets/Network.cs
@@ -0,0 +1,338 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Threading;
+
+using NLog.Internal;
+using NLog.Internal.NetworkSenders;
+using System.Text;
+using System.ComponentModel;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Sends logging messages over the network.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/Network/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/Network/Simple/Example.cs" />
+ /// <p>
+ /// To print the results, use any application that's able to receive messages over
+ /// TCP or UDP. <a href="http://m.nu/program/util/netcat/netcat.html">NetCat</a> is
+ /// a simple but very powerful command-line tool that can be used for that. This image
+ /// demonstrates the NetCat tool receiving log messages from Network target.
+ /// </p>
+ /// <img src="examples/targets/Screenshots/Network/Output.gif" />
+ /// <p>
+ /// NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol
+ /// or you'll get TCP timeouts and your application will crawl.
+ /// Either switch to UDP transport or use <a href="target.AsyncWrapper.html">AsyncWrapper</a> target
+ /// so that your application threads will not be blocked by the timing-out connection attempts.
+ /// </p>
+ /// <p>
+ /// There are two specialized versions of the Network target: <a href="target.Chainsaw.html">Chainsaw</a>
+ /// and <a href="target.NLogViewer.html">NLogViewer</a> which write to instances of Chainsaw log4j viewer
+ /// or NLogViewer application respectively.
+ /// </p>
+ /// </example>
+ [Target("Network")]
+ public class NetworkTarget: TargetWithLayout
+ {
+ private bool _newline = false;
+ private bool _keepConnection = true;
+ private Layout _addressLayout = null;
+ private NetworkSender _sender = null;
+ private Encoding _encoding = System.Text.Encoding.UTF8;
+ private OverflowAction _onOverflow = OverflowAction.Split;
+
+ /// <summary>
+ /// Action that should be taken if the message overflows.
+ /// </summary>
+ public enum OverflowAction
+ {
+ /// <summary>
+ /// Report an error.
+ /// </summary>
+ Error,
+
+ /// <summary>
+ /// Split the message into smaller pieces.
+ /// </summary>
+ Split,
+
+ /// <summary>
+ /// Discard the entire message
+ /// </summary>
+ Discard
+ }
+
+ /// <summary>
+ /// The network address. Can be tcp://host:port or udp://host:port
+ /// </summary>
+ /// <remarks>
+ /// For HTTP Support use the WebService target.
+ /// </remarks>
+ public string Address
+ {
+ get { return _addressLayout.Text; }
+ set
+ {
+ _addressLayout = new Layout(value);
+ if (_sender != null)
+ {
+ _sender.Close();
+ _sender = null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The network address. Can be tcp://host:port, udp://host:port, http://host:port or https://host:port
+ /// </summary>
+ public Layout AddressLayout
+ {
+ get { return _addressLayout; }
+ set { _addressLayout = value; }
+ }
+
+ /// <summary>
+ /// Keep connection open whenever possible.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool KeepConnection
+ {
+ get { return _keepConnection; }
+ set { _keepConnection = value; }
+ }
+
+ /// <summary>
+ /// Append newline at the end of log message.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool NewLine
+ {
+ get { return _newline; }
+ set { _newline = value; }
+ }
+
+ private int _maxMessageSize = 65000;
+
+ /// <summary>
+ /// Maximum message size in bytes.
+ /// </summary>
+ [DefaultValue(65000)]
+ public int MaxMessageSize
+ {
+ get { return _maxMessageSize; }
+ set { _maxMessageSize = value; }
+ }
+
+
+ /// <summary>
+ /// Action that should be taken if the message is larger than
+ /// maxMessageSize
+ /// </summary>
+ public OverflowAction OnOverflow
+ {
+ get { return _onOverflow; }
+ set { _onOverflow = value; }
+ }
+
+ /// <summary>
+ /// Encoding
+ /// </summary>
+ /// <remarks>
+ /// Can be any encoding name supported by System.Text.Encoding.GetEncoding() e.g. <c>windows-1252</c>, <c>iso-8859-2</c>.
+ /// </remarks>
+ [System.ComponentModel.DefaultValue("utf-8")]
+ public string Encoding
+ {
+ get { return _encoding.WebName; }
+ set { _encoding = System.Text.Encoding.GetEncoding(value); }
+ }
+
+ /// <summary>
+ /// Sends the provided text to the specified address.
+ /// </summary>
+ /// <param name="address">The address. Can be tcp://host:port, udp://host:port, http://host:port</param>
+ /// <param name="bytes">The bytes to be sent.</param>
+ protected virtual void NetworkSend(string address, byte[] bytes)
+ {
+ lock (this)
+ {
+ if (KeepConnection)
+ {
+ if (_sender != null)
+ {
+ if (_sender.Address != address)
+ {
+ _sender.Close();
+ _sender = null;
+ }
+ };
+ if (_sender == null)
+ {
+ _sender = NetworkSender.Create(address);
+ }
+
+ try
+ {
+ ChunkedSend(_sender, bytes);
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Error when sending {0}", ex);
+ _sender.Close();
+ _sender = null;
+ throw;
+ }
+ }
+ else
+ {
+ NetworkSender sender = NetworkSender.Create(address);
+
+ try
+ {
+ ChunkedSend(sender, bytes);
+ }
+ finally
+ {
+ sender.Close();
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Flushes any buffers.
+ /// </summary>
+ /// <param name="timeout">Flush timeout.</param>
+ public override void Flush(TimeSpan timeout)
+ {
+ lock (this)
+ {
+ if (_sender != null)
+ _sender.Flush();
+ }
+ }
+
+ /// <summary>
+ /// Closes the target.
+ /// </summary>
+ protected internal override void Close()
+ {
+ base.Close();
+ lock (this)
+ {
+ if (_sender != null)
+ _sender.Close();
+ }
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ base.PopulateLayouts(layouts);
+ AddressLayout.PopulateLayouts(layouts);
+ }
+
+ /// <summary>
+ /// Sends the
+ /// rendered logging event over the network optionally concatenating it with a newline character.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ NetworkSend(AddressLayout.GetFormattedMessage(logEvent), GetBytesToWrite(logEvent));
+ }
+
+ /// <summary>
+ /// Gets the bytes to be written.
+ /// </summary>
+ /// <param name="logEvent">Log event</param>
+ /// <returns>Byte array.</returns>
+ protected virtual byte[] GetBytesToWrite(LogEventInfo logEvent)
+ {
+ string text;
+
+ if (NewLine)
+ text = CompiledLayout.GetFormattedMessage(logEvent) + "\r\n";
+ else
+ text = CompiledLayout.GetFormattedMessage(logEvent);
+
+ return _encoding.GetBytes(text);
+ }
+
+ private void ChunkedSend(NetworkSender sender, byte[] buffer)
+ {
+ int tosend = buffer.Length;
+ int pos = 0;
+
+ while (tosend > 0)
+ {
+ int chunksize = tosend;
+ if (chunksize > MaxMessageSize)
+ {
+ if (OnOverflow == OverflowAction.Discard)
+ return;
+
+ if (OnOverflow == OverflowAction.Error)
+ throw new OverflowException("Attempted to send a message larger than MaxMessageSize(" + MaxMessageSize + "). Actual size was: " + buffer.Length + ". Adjust OnOverflow and MaxMessageSize parameters accordingly.");
+
+ chunksize = MaxMessageSize;
+ }
+ sender.Send(buffer, pos, chunksize);
+ tosend -= chunksize;
+ pos += chunksize;
+ }
+ }
+ }
+}
diff --git a/src/NLog/Targets/Null.cs b/src/NLog/Targets/Null.cs
new file mode 100644
index 0000000..beee1e9
--- /dev/null
+++ b/src/NLog/Targets/Null.cs
@@ -0,0 +1,87 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Discards logging messages optionally forcing the layouts to be calculated. Used mainly for debugging and benchmarking.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/Null/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/Null/Simple/Example.cs" />
+ /// </example>
+ [Target("Null")]
+ public sealed class NullTarget: TargetWithLayout
+ {
+ private bool _formatMessage = false;
+
+ /// <summary>
+ /// Perform layout calculation.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool FormatMessage
+ {
+ get { return _formatMessage; }
+ set { _formatMessage = value; }
+ }
+
+ /// <summary>
+ /// Does nothing. Optionally it calculates the layout text but
+ /// discards the results.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ if (_formatMessage)
+ {
+ CompiledLayout.GetFormattedMessage(logEvent);
+ }
+ }
+ }
+}
diff --git a/src/NLog/Targets/RichTextBox.cs b/src/NLog/Targets/RichTextBox.cs
new file mode 100644
index 0000000..b02c2df
--- /dev/null
+++ b/src/NLog/Targets/RichTextBox.cs
@@ -0,0 +1,260 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF && !MONO
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Text;
+using System.Text.RegularExpressions;
+
+using System.Windows.Forms;
+using System.Drawing;
+
+using NLog.Config;
+using NLog.Internal;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Log text to Text property of RichTextBox of specified Name
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/RichTextBox/Simple/NLog.config" />
+ /// <p>
+ /// The result is:
+ /// </p>
+ /// <img src="examples/targets/Screenshots/RichTextBox/Simple.gif" />
+ /// <p>
+ /// To set up the target with coloring rules in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/RichTextBox/RowColoring/NLog.config" />
+ /// <code lang="XML" src="examples/targets/Configuration File/RichTextBox/WordColoring/NLog.config" />
+ /// <p>
+ /// The result is:
+ /// </p>
+ /// <img src="examples/targets/Screenshots/RichTextBox/RowColoring.gif" />
+ /// <img src="examples/targets/Screenshots/RichTextBox/WordColoring.gif" />
+ /// <p>
+ /// To set up the log target programmatically similar to above use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/RichTextBox/Simple/Form1.cs" />,
+ /// <code lang="C#" src="examples/targets/Configuration API/RichTextBox/RowColoring/Form1.cs" /> for RowColoring,
+ /// <code lang="C#" src="examples/targets/Configuration API/RichTextBox/WordColoring/Form1.cs" /> for WordColoring
+ /// </example>
+ [Target("RichTextBox")]
+ [SupportedRuntime(Framework = RuntimeFramework.DotNetFramework, MinRuntimeVersion = "1.1")]
+ public sealed class RichTextBoxTarget : TargetWithLayout
+ {
+ private string _controlName;
+ private string _formName;
+ private bool _useDefaultRowColoringRules = false;
+ private RichTextBoxRowColoringRuleCollection _richTextBoxRowColoringRules = new RichTextBoxRowColoringRuleCollection();
+ private RichTextBoxWordColoringRuleCollection _richTextBoxWordColoringRules = new RichTextBoxWordColoringRuleCollection();
+ private static RichTextBoxRowColoringRuleCollection _defaultRichTextBoxRowColoringRules = new RichTextBoxRowColoringRuleCollection();
+
+ static RichTextBoxTarget()
+ {
+ _defaultRichTextBoxRowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Fatal", "White", "Red", FontStyle.Bold));
+ _defaultRichTextBoxRowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Error", "Red", "Empty", FontStyle.Bold | FontStyle.Italic));
+ _defaultRichTextBoxRowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Warn", "Orange", "Empty", FontStyle.Underline));
+ _defaultRichTextBoxRowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Info", "Black", "Empty"));
+ _defaultRichTextBoxRowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Debug", "Gray", "Empty"));
+ _defaultRichTextBoxRowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Trace", "DarkGray", "Empty", FontStyle.Italic));
+ }
+
+ /// <summary>
+ /// Name of RichTextBox to which Nlog will log
+ /// </summary>
+ [RequiredParameter]
+ public string ControlName
+ {
+ get { return _controlName; }
+ set { _controlName = value; }
+ }
+
+ /// <summary>
+ /// Name of the Form on which the control is located.
+ /// If there is no open form of a specified name than NLog will create a new one.
+ /// </summary>
+ public string FormName
+ {
+ get { return _formName; }
+ set { _formName = value; }
+ }
+
+ /// <summary>
+ /// Use default coloring rules
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool UseDefaultRowColoringRules
+ {
+ get { return _useDefaultRowColoringRules; }
+ set { _useDefaultRowColoringRules = value; }
+ }
+
+ /// <summary>
+ /// Row coloring rules.
+ /// </summary>
+ [ArrayParameter(typeof(RichTextBoxRowColoringRule), "row-coloring")]
+ public RichTextBoxRowColoringRuleCollection RowColoringRules
+ {
+ get { return _richTextBoxRowColoringRules; }
+ }
+
+ /// <summary>
+ /// Word highlighting rules.
+ /// </summary>
+ [ArrayParameter(typeof(RichTextBoxWordColoringRule), "word-coloring")]
+ public RichTextBoxWordColoringRuleCollection WordColoringRules
+ {
+ get { return _richTextBoxWordColoringRules; }
+ }
+
+ /// <summary>
+ /// Log message to RichTextBox
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ RichTextBoxRowColoringRule matchingRule = null;
+
+ foreach (RichTextBoxRowColoringRule rr in RowColoringRules)
+ {
+ if (rr.CheckCondition(logEvent))
+ {
+ matchingRule = rr;
+ break;
+ }
+ }
+
+ if (UseDefaultRowColoringRules && matchingRule == null)
+ {
+ foreach (RichTextBoxRowColoringRule rr in _defaultRichTextBoxRowColoringRules)
+ {
+ if (rr.CheckCondition(logEvent))
+ {
+ matchingRule = rr;
+ break;
+ }
+ }
+ }
+
+ if (matchingRule == null)
+ matchingRule = RichTextBoxRowColoringRule.Default;
+
+ string logMessage = CompiledLayout.GetFormattedMessage(logEvent);
+
+ FindRichTextBoxAndSendTheMessage(logMessage, matchingRule);
+ }
+
+ private void FindRichTextBoxAndSendTheMessage(string logMessage, RichTextBoxRowColoringRule rule)
+ {
+ Form form = null;
+ bool createdForm = false;
+
+ if (Form.ActiveForm != null && Form.ActiveForm.Name == FormName)
+ {
+ form = Form.ActiveForm;
+ }
+
+#if DOTNET_2_0
+ if (form == null && Application.OpenForms[FormName] != null)
+ form = Application.OpenForms[FormName];
+#endif
+ if (form == null)
+ {
+ form = FormHelper.CreateForm(FormName, 0, 0, true);
+ createdForm = true;
+ }
+
+ RichTextBox rtbx = (RichTextBox)FormHelper.FindControl(ControlName, form, typeof(RichTextBox));
+
+ if (rtbx == null && createdForm)
+ rtbx = FormHelper.CreateRichTextBox(ControlName, form);
+ else if (rtbx == null && !createdForm)
+ return;
+
+ rtbx.Invoke(new DelSendTheMessageToRichTextBox(SendTheMessageToRichTextBox), new object[] { rtbx, logMessage, rule });
+ }
+
+ private delegate void DelSendTheMessageToRichTextBox(RichTextBox rtbx, string logMessage, RichTextBoxRowColoringRule rule);
+
+ private void SendTheMessageToRichTextBox(RichTextBox rtbx, string logMessage, RichTextBoxRowColoringRule rule)
+ {
+ int startIndex = rtbx.Text.Length;
+ rtbx.SelectionStart = startIndex;
+#if DOTNET_2_0
+ rtbx.SelectionBackColor = GetColorFromString(rule.BackgroundColor, rtbx.BackColor);
+#endif
+ rtbx.SelectionColor = GetColorFromString(rule.FontColor, rtbx.ForeColor);
+ rtbx.SelectionFont = new Font(rtbx.SelectionFont, rtbx.SelectionFont.Style ^ rule.Style);
+ rtbx.AppendText(logMessage + "\n");
+ rtbx.SelectionLength = rtbx.Text.Length - rtbx.SelectionStart;
+
+ // find word to color
+ foreach (RichTextBoxWordColoringRule wordRule in WordColoringRules)
+ {
+ MatchCollection mc = wordRule.CompiledRegex.Matches(rtbx.Text, startIndex);
+ foreach (Match m in mc)
+ {
+ rtbx.SelectionStart = m.Index;
+ rtbx.SelectionLength = m.Length;
+#if DOTNET_2_0
+ rtbx.SelectionBackColor = GetColorFromString(wordRule.BackgroundColor, rtbx.BackColor);
+#endif
+ rtbx.SelectionColor = GetColorFromString(wordRule.FontColor, rtbx.ForeColor);
+ rtbx.SelectionFont = new Font(rtbx.SelectionFont, rtbx.SelectionFont.Style ^ wordRule.Style);
+ }
+ }
+ }
+
+ private Color GetColorFromString(string color, Color defaultColor)
+ {
+ if (color == "Empty") return defaultColor;
+
+ Color c = Color.FromName(color);
+ if (c == Color.Empty) return defaultColor;
+
+ return c;
+ }
+ }
+}
+#endif
diff --git a/src/NLog/Targets/RichTextBoxRowColoringRule.cs b/src/NLog/Targets/RichTextBoxRowColoringRule.cs
new file mode 100644
index 0000000..f2f4a62
--- /dev/null
+++ b/src/NLog/Targets/RichTextBoxRowColoringRule.cs
@@ -0,0 +1,161 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF && !MONO
+
+using System;
+using System.Text;
+using System.Drawing;
+
+using NLog.Conditions;
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// The row-coloring condition.
+ /// </summary>
+ public class RichTextBoxRowColoringRule
+ {
+ private ConditionExpression _condition = null;
+ private string _fontColor = "Empty";
+ private string _backColor = "Empty";
+ private FontStyle _style;
+ /// <summary>
+ /// Default highlighting rule. Doesn't change the color.
+ /// </summary>
+ public static readonly RichTextBoxRowColoringRule Default = new RichTextBoxRowColoringRule(null, "Empty", "Empty");
+
+ /// <summary>
+ /// The condition that must be met in order to set the specified font color.
+ /// </summary>
+ [AcceptsCondition]
+ [RequiredParameter]
+ public string Condition
+ {
+ get
+ {
+ if (_condition == null)
+ return null;
+ else
+ return _condition.ToString();
+ }
+ set
+ {
+ if (value != null)
+ _condition = ConditionParser.ParseExpression(value);
+ else
+ _condition = null;
+ }
+ }
+
+ /// <summary>
+ /// The font color.
+ /// Names are identical with KnownColor enum extended with Empty value which means that background color won't be changed
+ /// </summary>
+ [System.ComponentModel.DefaultValue("Empty")]
+ public string FontColor
+ {
+ get { return _fontColor; }
+ set { _fontColor = value; }
+ }
+
+ /// <summary>
+ /// The background color.
+ /// Names are identical with KnownColor enum extended with Empty value which means that background color won't be changed
+ /// Background color will be set only in .net 2.0
+ /// </summary>
+ [System.ComponentModel.DefaultValue("Empty")]
+ [SupportedRuntime(Framework = RuntimeFramework.DotNetFramework, MinRuntimeVersion = "2.0")]
+ public string BackgroundColor
+ {
+ get { return _backColor; }
+ set { _backColor = value; }
+ }
+
+ /// <summary>
+ /// Font style of matched text.
+ /// Possible values are the same as in <c>FontStyle</c> enum in <c>System.Drawing</c>
+ /// </summary>
+ public FontStyle Style
+ {
+ get { return _style; }
+ set { _style = value; }
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="RichTextBoxRowColoringRule"/>
+ /// </summary>
+ public RichTextBoxRowColoringRule()
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="RichTextBoxRowColoringRule"/> and
+ /// assigns Condition, FontColor and FontStyle properties.
+ /// </summary>
+ public RichTextBoxRowColoringRule(string condition, string fontColor, string backColor, FontStyle fontStyle)
+ {
+ Condition = condition;
+ FontColor = fontColor;
+ BackgroundColor = backColor;
+ Style = fontStyle;
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="RichTextBoxRowColoringRule"/> and
+ /// assigns Condition and FontColor properties with regular style of font
+ /// </summary>
+ public RichTextBoxRowColoringRule(string condition, string fontColor, string backColor)
+ {
+ Condition = condition;
+ FontColor = fontColor;
+ BackgroundColor = backColor;
+ Style = FontStyle.Regular;
+ }
+
+ /// <summary>
+ /// Checks whether the specified log event matches the condition (if any)
+ /// </summary>
+ /// <param name="logEvent">log event</param>
+ /// <returns><see langword="true"/> if the condition is not defined or
+ /// if it matches, <see langword="false"/> otherwise</returns>
+ public bool CheckCondition(LogEventInfo logEvent)
+ {
+ if (_condition == null)
+ return true;
+ return true.Equals(_condition.Evaluate(logEvent));
+ }
+ }
+}
+#endif
diff --git a/src/NLog/Targets/RichTextBoxRowColoringRuleCollection.cs b/src/NLog/Targets/RichTextBoxRowColoringRuleCollection.cs
new file mode 100644
index 0000000..2bea4f4
--- /dev/null
+++ b/src/NLog/Targets/RichTextBoxRowColoringRuleCollection.cs
@@ -0,0 +1,255 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF && !MONO
+
+using System;
+using System.Runtime.InteropServices;
+
+using NLog.Targets;
+
+namespace NLog
+{
+ /// <summary>
+ /// A collection of elements of type RichTextBoxRowColoringRule
+ /// </summary>
+ public class RichTextBoxRowColoringRuleCollection : System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the RichTextBoxRowColoringRuleCollection class.
+ /// </summary>
+ public RichTextBoxRowColoringRuleCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the RichTextBoxRowColoringRuleCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new RichTextBoxRowColoringRuleCollection.
+ /// </param>
+ public RichTextBoxRowColoringRuleCollection(RichTextBoxRowColoringRule[] items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the RichTextBoxRowColoringRuleCollection class, containing elements
+ /// copied from another instance of RichTextBoxRowColoringRuleCollection
+ /// </summary>
+ /// <param name="items">
+ /// The RichTextBoxRowColoringRuleCollection whose elements are to be added to the new RichTextBoxRowColoringRuleCollection.
+ /// </param>
+ public RichTextBoxRowColoringRuleCollection(RichTextBoxRowColoringRuleCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this RichTextBoxRowColoringRuleCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this RichTextBoxRowColoringRuleCollection.
+ /// </param>
+ public virtual void AddRange(RichTextBoxRowColoringRule[] items)
+ {
+ foreach (RichTextBoxRowColoringRule item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another RichTextBoxRowColoringRuleCollection to the end of this RichTextBoxRowColoringRuleCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The RichTextBoxRowColoringRuleCollection whose elements are to be added to the end of this RichTextBoxRowColoringRuleCollection.
+ /// </param>
+ public virtual void AddRange(RichTextBoxRowColoringRuleCollection items)
+ {
+ foreach (RichTextBoxRowColoringRule item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type RichTextBoxWordColoringRule to the end of this RichTextBoxRowColoringRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The RichTextBoxRowColoringRule to be added to the end of this RichTextBoxRowColoringRuleCollection.
+ /// </param>
+ public virtual void Add(RichTextBoxRowColoringRule value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic RichTextBoxRowColoringRule value is in this RichTextBoxRowColoringRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The RichTextBoxRowColoringRule value to locate in this RichTextBoxRowColoringRuleCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this RichTextBoxRowColoringRuleCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(RichTextBoxRowColoringRule value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this RichTextBoxRowColoringRuleCollection
+ /// </summary>
+ /// <param name="value">
+ /// The RichTextBoxRowColoringRule value to locate in the RichTextBoxRowColoringRuleCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(RichTextBoxRowColoringRule value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the RichTextBoxRowColoringRuleCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the RichTextBoxRowColoringRule is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The RichTextBoxRowColoringRule to insert.
+ /// </param>
+ public virtual void Insert(int index, RichTextBoxRowColoringRule value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the RichTextBoxRowColoringRule at the given index in this RichTextBoxRowColoringRuleCollection.
+ /// </summary>
+ public virtual RichTextBoxRowColoringRule this[int index]
+ {
+ get
+ {
+ return (RichTextBoxRowColoringRule)this.List[index];
+ }
+ set
+ {
+ this.List[index] = value;
+ }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific RichTextBoxRowColoringRule from this RichTextBoxRowColoringRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The RichTextBoxRowColoringRule value to remove from this RichTextBoxRowColoringRuleCollection.
+ /// </param>
+ public virtual void Remove(RichTextBoxRowColoringRule value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by RichTextBoxRowColoringRuleCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator : System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(RichTextBoxRowColoringRuleCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public RichTextBoxRowColoringRule Current
+ {
+ get
+ {
+ return (RichTextBoxRowColoringRule)(this.wrapped.Current);
+ }
+ }
+
+ object System.Collections.IEnumerator.Current
+ {
+ get
+ {
+ return (RichTextBoxRowColoringRule)(this.wrapped.Current);
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this RichTextBoxRowColoringRuleCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual RichTextBoxRowColoringRuleCollection.Enumerator GetEnumerator()
+ {
+ return new RichTextBoxRowColoringRuleCollection.Enumerator(this);
+ }
+ }
+}
+#endif
diff --git a/src/NLog/Targets/RichTextBoxWordColoringRule.cs b/src/NLog/Targets/RichTextBoxWordColoringRule.cs
new file mode 100644
index 0000000..38842b2
--- /dev/null
+++ b/src/NLog/Targets/RichTextBoxWordColoringRule.cs
@@ -0,0 +1,195 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF && !MONO
+
+using System;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Runtime.InteropServices;
+using System.Windows.Forms;
+
+using NLog.Config;
+using NLog.Conditions;
+using NLog.Targets;
+using System.Drawing;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Highlighting rule for Win32 colorful console.
+ /// </summary>
+ public class RichTextBoxWordColoringRule
+ {
+ private string _text;
+ private string _regex;
+ private bool _wholeWords = false;
+ private bool _ignoreCase = false;
+ private Regex _compiledRegex;
+ private string _fontColor = "Empty";
+ private string _backColor = "Empty";
+ private FontStyle _style;
+
+ /// <summary>
+ /// The regular expression to be matched. You must specify either <c>text</c> or <c>regex</c>.
+ /// </summary>
+ public string Regex
+ {
+ get { return _regex; }
+ set { _regex = value; }
+ }
+
+ /// <summary>
+ /// The text to be matched. You must specify either <c>text</c> or <c>regex</c>.
+ /// </summary>
+ public string Text
+ {
+ get { return _text; }
+ set { _text = value; }
+ }
+
+ /// <summary>
+ /// Font style of matched text.
+ /// Possible values are the same as in <c>FontStyle</c> enum in <c>System.Drawing</c>
+ /// </summary>
+ public FontStyle Style
+ {
+ get { return _style; }
+ set { _style = value; }
+ }
+
+ /// <summary>
+ /// Match whole words only.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool WholeWords
+ {
+ get { return _wholeWords; }
+ set { _wholeWords = value; }
+ }
+
+ /// <summary>
+ /// Ignore case when comparing texts.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool IgnoreCase
+ {
+ get { return _ignoreCase; }
+ set { _ignoreCase = value; }
+ }
+
+ /// <summary>
+ /// Compiled regular expression that matches either Text or Regex property.
+ /// </summary>
+ public Regex CompiledRegex
+ {
+ get
+ {
+ if (_compiledRegex == null)
+ {
+ string regexpression = _regex;
+ if (regexpression == null && _text != null)
+ {
+ regexpression = System.Text.RegularExpressions.Regex.Escape(_text);
+ if (WholeWords)
+ regexpression = "\b" + regexpression + "\b";
+ }
+
+ RegexOptions regexOptions = RegexOptions.Compiled;
+ if (IgnoreCase)
+ regexOptions |= RegexOptions.IgnoreCase;
+
+ _compiledRegex = new Regex(regexpression, regexOptions);
+ }
+
+ return _compiledRegex;
+ }
+ }
+
+ /// <summary>
+ /// The font color.
+ /// Names are identical with KnownColor enum extended with Empty value which means that font color won't be changed
+ /// </summary>
+ [System.ComponentModel.DefaultValue("Empty")]
+ public string FontColor
+ {
+ get { return _fontColor; }
+ set { _fontColor = value; }
+ }
+
+ /// <summary>
+ /// The background color.
+ /// Names are identical with KnownColor enum extended with Empty value which means that background color won't be changed
+ /// Background color will be set only in .net 2.0
+ /// </summary>
+ [System.ComponentModel.DefaultValue("Empty")]
+ [SupportedRuntime(Framework = RuntimeFramework.DotNetFramework, MinRuntimeVersion = "2.0")]
+ public string BackgroundColor
+ {
+ get { return _backColor; }
+ set { _backColor = value; }
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="RichTextBoxWordColoringRule"/>
+ /// </summary>
+ public RichTextBoxWordColoringRule()
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="RichTextBoxWordColoringRule"/>
+ /// and sets Text, BackgroundColor and ForegroundColor properties.
+ /// </summary>
+ public RichTextBoxWordColoringRule(string text, string fontColor, string backgroundColor)
+ {
+ Text = text;
+ FontColor = fontColor;
+ BackgroundColor = backgroundColor;
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="RichTextBoxWordColoringRule"/>
+ /// and sets Text, BackgroundColor, FontColor and Style properties.
+ /// </summary>
+ public RichTextBoxWordColoringRule(string text, string fontColor, string backgroundColor, FontStyle fontStyle)
+ {
+ Text = text;
+ FontColor = fontColor;
+ BackgroundColor = backgroundColor;
+ Style = fontStyle;
+ }
+
+ }
+}
+#endif
diff --git a/src/NLog/Targets/RichTextBoxWordColoringRuleCollection.cs b/src/NLog/Targets/RichTextBoxWordColoringRuleCollection.cs
new file mode 100644
index 0000000..6420a1f
--- /dev/null
+++ b/src/NLog/Targets/RichTextBoxWordColoringRuleCollection.cs
@@ -0,0 +1,240 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF && !MONO
+
+using System;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// A collection of elements of type RichTextBoxWordColoringRule
+ /// </summary>
+ public class RichTextBoxWordColoringRuleCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the RichTextBoxWordColoringRuleCollection class.
+ /// </summary>
+ public RichTextBoxWordColoringRuleCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the RichTextBoxWordColoringRuleCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new RichTextBoxWordColoringRuleCollection.
+ /// </param>
+ public RichTextBoxWordColoringRuleCollection(RichTextBoxWordColoringRule[] items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the RichTextBoxWordColoringRuleCollection class, containing elements
+ /// copied from another instance of RichTextBoxWordColoringRuleCollection
+ /// </summary>
+ /// <param name="items">
+ /// The RichTextBoxWordColoringRuleCollection whose elements are to be added to the new RichTextBoxWordColoringRuleCollection.
+ /// </param>
+ public RichTextBoxWordColoringRuleCollection(RichTextBoxWordColoringRuleCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this RichTextBoxWordColoringRuleCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this RichTextBoxWordColoringRuleCollection.
+ /// </param>
+ public virtual void AddRange(RichTextBoxWordColoringRule[] items)
+ {
+ foreach (RichTextBoxWordColoringRule item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another RichTextBoxWordColoringRuleCollection to the end of this RichTextBoxWordColoringRuleCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The RichTextBoxWordColoringRuleCollection whose elements are to be added to the end of this RichTextBoxWordColoringRuleCollection.
+ /// </param>
+ public virtual void AddRange(RichTextBoxWordColoringRuleCollection items)
+ {
+ foreach (RichTextBoxWordColoringRule item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type RichTextBoxWordColoringRule to the end of this RichTextBoxWordColoringRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The RichTextBoxWordColoringRule to be added to the end of this RichTextBoxWordColoringRuleCollection.
+ /// </param>
+ public virtual void Add(RichTextBoxWordColoringRule value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic RichTextBoxWordColoringRule value is in this RichTextBoxWordColoringRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The RichTextBoxWordColoringRule value to locate in this RichTextBoxWordColoringRuleCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this RichTextBoxWordColoringRuleCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(RichTextBoxWordColoringRule value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this RichTextBoxWordColoringRuleCollection
+ /// </summary>
+ /// <param name="value">
+ /// The RichTextBoxWordColoringRule value to locate in the RichTextBoxWordColoringRuleCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(RichTextBoxWordColoringRule value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the RichTextBoxWordColoringRuleCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the RichTextBoxWordColoringRule is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The RichTextBoxWordColoringRule to insert.
+ /// </param>
+ public virtual void Insert(int index, RichTextBoxWordColoringRule value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the RichTextBoxWordColoringRule at the given index in this RichTextBoxWordColoringRuleCollection.
+ /// </summary>
+ public virtual RichTextBoxWordColoringRule this[int index]
+ {
+ get { return (RichTextBoxWordColoringRule) this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific RichTextBoxWordColoringRule from this RichTextBoxWordColoringRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The RichTextBoxWordColoringRule value to remove from this RichTextBoxWordColoringRuleCollection.
+ /// </param>
+ public virtual void Remove(RichTextBoxWordColoringRule value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by RichTextBoxWordColoringRuleCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(RichTextBoxWordColoringRuleCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public RichTextBoxWordColoringRule Current
+ {
+ get { return (RichTextBoxWordColoringRule) (this.wrapped.Current); }
+ }
+
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (RichTextBoxWordColoringRule) (this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this RichTextBoxWordColoringRuleCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual RichTextBoxWordColoringRuleCollection.Enumerator GetEnumerator()
+ {
+ return new RichTextBoxWordColoringRuleCollection.Enumerator(this);
+ }
+ }
+}
+#endif
diff --git a/src/NLog/Targets/Trace.cs b/src/NLog/Targets/Trace.cs
new file mode 100644
index 0000000..8c19340
--- /dev/null
+++ b/src/NLog/Targets/Trace.cs
@@ -0,0 +1,87 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#define TRACE
+
+#if !NETCF
+using System;
+using System.Diagnostics;
+
+using NLog.Config;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Sends logging messages through System.Diagnostics.Trace
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/Trace/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/Trace/Simple/Example.cs" />
+ /// </example>
+ [Target("Trace")]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public sealed class TraceTarget: TargetWithLayout
+ {
+ /// <summary>
+ /// Writes the specified logging event to the <see cref="System.Diagnostics.Trace"/> facility.
+ /// If the log level is greater than or equal to <see cref="LogLevel.Error"/> it uses the
+ /// <see cref="System.Diagnostics.Trace.Fail(String)"/> method, otherwise it uses
+ /// <see cref="System.Diagnostics.Trace.Write(String)" /> method.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ if (logEvent.Level >= LogLevel.Error)
+ {
+ Trace.Fail(CompiledLayout.GetFormattedMessage(logEvent));
+ }
+ else
+ {
+ Trace.WriteLine(CompiledLayout.GetFormattedMessage(logEvent));
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Targets/WebService.cs b/src/NLog/Targets/WebService.cs
new file mode 100644
index 0000000..5e0884d
--- /dev/null
+++ b/src/NLog/Targets/WebService.cs
@@ -0,0 +1,266 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Reflection;
+using System.Web.Services.Protocols;
+
+using NLog.Config;
+using System.IO;
+using System.Xml;
+using System.Net;
+
+namespace NLog.Targets
+{
+ /// <summary>
+ /// Calls the specified web service on each logging message.
+ /// </summary>
+ /// <remarks>
+ /// The web service must implement a method that accepts a number of string parameters.
+ /// </remarks>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/WebService/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/WebService/Simple/Example.cs" />
+ /// <p>The example web service that works with this example is shown below</p>
+ /// <code lang="C#" src="examples/targets/Configuration API/WebService/Simple/WebService1/Service1.asmx.cs" />
+ /// </example>
+ [Target("WebService")]
+ public sealed class WebServiceTarget: MethodCallTargetBase
+ {
+ const string soapEnvelopeNamespace = "http://schemas.xmlsoap.org/soap/envelope/";
+ const string soap12EnvelopeNamespace = "http://www.w3.org/2003/05/soap-envelope";
+
+ /// <summary>
+ /// Web service protocol
+ /// </summary>
+ public enum WebServiceProtocol
+ {
+ /// <summary>
+ /// SOAP 1.1
+ /// </summary>
+ Soap11,
+
+ /// <summary>
+ /// SOAP 1.2
+ /// </summary>
+ Soap12,
+
+ /// <summary>
+ /// HTTP POST
+ /// </summary>
+ HttpPost,
+
+ /// <summary>
+ /// HTTP GET
+ /// </summary>
+ HttpGet,
+ }
+
+ private string _methodName = null;
+ private string _url = null;
+ private string _namespace = null;
+ private WebServiceProtocol _protocol = WebServiceProtocol.Soap11;
+
+ /// <summary>
+ /// Web service URL.
+ /// </summary>
+ public string Url
+ {
+ get { return _url; }
+ set { _url = value; }
+ }
+
+ /// <summary>
+ /// Web service method name.
+ /// </summary>
+ public string MethodName
+ {
+ get { return _methodName; }
+ set { _methodName = value; }
+ }
+
+ /// <summary>
+ /// Web service namespace.
+ /// </summary>
+ public string Namespace
+ {
+ get { return _namespace; }
+ set { _namespace = value; }
+ }
+
+ /// <summary>
+ /// The protocol to be used when calling web service.
+ /// </summary>
+ [System.ComponentModel.DefaultValue("Soap11")]
+ public WebServiceProtocol Protocol
+ {
+ get { return _protocol; }
+ set { _protocol = value; }
+ }
+
+ /// <summary>
+ /// Invokes the web service method.
+ /// </summary>
+ /// <param name="parameters">Parameters to be passed.</param>
+ protected override void DoInvoke(object[]parameters)
+ {
+ switch (_protocol)
+ {
+ case WebServiceProtocol.Soap11:
+ InvokeSoap11(parameters);
+ break;
+
+ case WebServiceProtocol.Soap12:
+ InvokeSoap12(parameters);
+ break;
+
+ case WebServiceProtocol.HttpGet:
+ InvokeHttpGet(parameters);
+ break;
+
+ case WebServiceProtocol.HttpPost:
+ InvokeHttpPost(parameters);
+ break;
+ }
+ //_client.DoInvoke(MethodName, parameters);
+ }
+
+ private void InvokeSoap11(object[] parameters)
+ {
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
+ request.Method = "POST";
+ request.ContentType = "text/xml; charset=utf-8";
+
+ string soapAction;
+
+ if (Namespace.EndsWith("/"))
+ soapAction = "SOAPAction: " + Namespace + MethodName;
+ else
+ soapAction = "SOAPAction: " + Namespace + "/" + MethodName;
+ request.Headers.Add(soapAction);
+
+ using (Stream s = request.GetRequestStream())
+ {
+ XmlTextWriter xtw = new XmlTextWriter(s, System.Text.Encoding.UTF8);
+
+ xtw.WriteStartElement("soap", "Envelope", soapEnvelopeNamespace);
+ xtw.WriteStartElement("Body", soapEnvelopeNamespace);
+ xtw.WriteStartElement(MethodName, Namespace);
+ for (int i = 0; i < Parameters.Count; ++i)
+ {
+ xtw.WriteElementString(Parameters[i].Name, Convert.ToString(parameters[i]));
+ }
+ xtw.WriteEndElement();
+ xtw.WriteEndElement();
+ xtw.WriteEndElement();
+ xtw.Flush();
+ }
+
+ WebResponse response = request.GetResponse();
+ response.Close();
+ }
+
+ private void InvokeSoap12(object[] parameters)
+ {
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
+ request.Method = "POST";
+ request.ContentType = "text/xml; charset=utf-8";
+
+ using (Stream s = request.GetRequestStream())
+ {
+ XmlTextWriter xtw = new XmlTextWriter(s, System.Text.Encoding.UTF8);
+
+ xtw.WriteStartElement("soap12", "Envelope", soap12EnvelopeNamespace);
+ xtw.WriteStartElement("Body", soap12EnvelopeNamespace);
+ xtw.WriteStartElement(MethodName, Namespace);
+ for (int i = 0; i < Parameters.Count; ++i)
+ {
+ xtw.WriteElementString(Parameters[i].Name, Convert.ToString(parameters[i]));
+ }
+ xtw.WriteEndElement();
+ xtw.WriteEndElement();
+ xtw.WriteEndElement();
+ xtw.Flush();
+ }
+
+ WebResponse response = request.GetResponse();
+ response.Close();
+ }
+
+ private void InvokeHttpPost(object[] parameters)
+ {
+ string CompleteUrl;
+
+ if (MethodName.EndsWith("/"))
+ CompleteUrl = Url + MethodName;
+ else
+ CompleteUrl = Url + "/" + MethodName;
+
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(CompleteUrl);
+ request.Method = "POST";
+ request.ContentType = "application/x-www-form-urlencoded";
+
+ using (Stream s = request.GetRequestStream())
+ using (StreamWriter sw = new StreamWriter(s))
+ {
+ for (int i = 0; i < Parameters.Count; ++i)
+ {
+ sw.Write(Parameters[i].Name + "=" + System.Web.HttpUtility.UrlEncodeUnicode(Convert.ToString(parameters[i])) + ((i < (Parameters.Count - 1)) ? "&" : ""));
+ }
+ sw.Flush();
+ }
+
+ WebResponse response = request.GetResponse();
+ response.Close();
+ }
+
+ private void InvokeHttpGet(object[] parameters)
+ {
+ throw new NotSupportedException();
+ }
+ }
+}
diff --git a/src/NLog/Targets/Wrappers/ASPNetBufferingTargetWrapper.cs b/src/NLog/Targets/Wrappers/ASPNetBufferingTargetWrapper.cs
new file mode 100644
index 0000000..e51d62c
--- /dev/null
+++ b/src/NLog/Targets/Wrappers/ASPNetBufferingTargetWrapper.cs
@@ -0,0 +1,235 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Web;
+
+using NLog.Config;
+
+namespace NLog.Targets.Wrappers
+{
+ /// <summary>
+ /// A target that buffers log events for the duration of
+ /// the ASP.NET Request and sends them down to the wrapped target
+ /// as soon as the request ends.
+ /// </summary>
+ /// <remarks>
+ /// <p>
+ /// Typically this target is used in cooperation with PostFilteringTargetWrapper
+ /// to provide verbose logging for failing requests and normal or no logging for
+ /// successful requests. We need to make the decision of the final filtering rule
+ /// to apply after all logs for a page have been generated.
+ /// </p>
+ /// <p>
+ /// To use this target, you need to add an entry in the httpModules section of
+ /// web.config:
+ /// </p>
+ /// <code lang="XML">
+ /// <![CDATA[<?xml version="1.0" ?>
+ /// <configuration>
+ /// <system.web>
+ /// <httpModules>
+ /// <add name="NLog" type="NLog.Web.NLogHttpModule, NLog"/>
+ /// </httpModules>
+ /// </system.web>
+ /// </configuration>
+ /// ]]>
+ /// </code>
+ /// </remarks>
+ /// <example>
+ /// <p>To set up the ASP.NET Buffering target wrapper <a href="config.html">configuration file</a>, put
+ /// the following in <c>web.nlog</c> file in your web application directory (this assumes
+ /// that PostFilteringWrapper is used to provide the filtering and actual logs go to
+ /// a file).
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/ASPNetBufferingWrapper/web.nlog" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To configure the target programmatically, put the following
+ /// piece of code in your <c>Application_OnStart()</c> handler in Global.asax.cs
+ /// or some other place that gets executed at the very beginning of your code:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/ASPNetBufferingWrapper/Global.asax.cs" />
+ /// <p>
+ /// Fully working C# project can be found in the <c>Examples/Targets/Configuration API/ASPNetBufferingWrapper</c>
+ /// directory along with usage instructions.
+ /// </p>
+ /// </example>
+ [Target("ASPNetBufferingWrapper", IgnoresLayout = true, IsWrapper = true)]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class ASPNetBufferingTargetWrapper: WrapperTargetBase
+ {
+ private object _dataSlot = new object();
+ private int _bufferSize = 100;
+ private int _growLimit = 0;
+ private bool _growBufferAsNeeded = true;
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="ASPNetBufferingTargetWrapper"/> and initializes <see cref="BufferSize"/> to 100.
+ /// </summary>
+ public ASPNetBufferingTargetWrapper()
+ {
+ BufferSize = 100;
+ GrowBufferAsNeeded = true;
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="ASPNetBufferingTargetWrapper"/>, initializes <see cref="BufferSize"/> to 100 and
+ /// sets the <see cref="WrapperTargetBase.WrappedTarget"/> to the specified value.
+ /// </summary>
+ public ASPNetBufferingTargetWrapper(Target writeTo) : this(writeTo, 100)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="ASPNetBufferingTargetWrapper"/>, initializes <see cref="BufferSize"/> and
+ /// the <see cref="WrapperTargetBase.WrappedTarget"/> to the specified values.
+ /// </summary>
+ public ASPNetBufferingTargetWrapper(Target writeTo, int bufferSize)
+ {
+ WrappedTarget = writeTo;
+ BufferSize = bufferSize;
+ }
+
+ /// <summary>
+ /// The number of log events to be buffered.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(4000)]
+ public int BufferSize
+ {
+ get { return _bufferSize; }
+ set { _bufferSize = value; }
+ }
+
+ /// <summary>
+ /// Grow the buffer when it gets full.
+ /// </summary>
+ /// <remarks>
+ /// true causes the buffer to expand until <see cref="BufferGrowLimit" /> is hit,
+ /// false causes the buffer to never expand and lose the earliest entries in case of overflow.
+ /// </remarks>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool GrowBufferAsNeeded
+ {
+ get { return _growBufferAsNeeded; }
+ set { _growBufferAsNeeded = value; }
+ }
+
+ /// <summary>
+ /// The maximum number of log events that the buffer can keep.
+ /// </summary>
+ public int BufferGrowLimit
+ {
+ get { return _growLimit; }
+ set
+ {
+ _growLimit = value;
+ GrowBufferAsNeeded = (value >= _bufferSize) ? true : false;
+ }
+ }
+
+ /// <summary>
+ /// Initializes the target by hooking up the NLogHttpModule BeginRequest and EndRequest events.
+ /// </summary>
+ public override void Initialize()
+ {
+ base.Initialize();
+ NLog.Web.NLogHttpModule.BeginRequest += new EventHandler(this.OnBeginRequest);
+ NLog.Web.NLogHttpModule.EndRequest += new EventHandler(this.OnEndRequest);
+ }
+
+ /// <summary>
+ /// Adds the specified log event to the buffer.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ WrappedTarget.PrecalculateVolatileLayouts(logEvent);
+ LogEventInfoBuffer buffer = GetRequestBuffer();
+ if (buffer != null)
+ {
+ buffer.Append(logEvent);
+ }
+ }
+
+ /// <summary>
+ /// Closes the target by flushing pending events in the buffer (if any).
+ /// </summary>
+ protected internal override void Close()
+ {
+ Flush(TimeSpan.FromSeconds(3));
+ base.Close ();
+ }
+
+ private LogEventInfoBuffer GetRequestBuffer()
+ {
+ HttpContext context = HttpContext.Current;
+ if (context == null)
+ return null;
+ return context.Items[_dataSlot] as LogEventInfoBuffer;
+ }
+
+ private void OnBeginRequest(object sender, EventArgs args)
+ {
+ HttpContext context = HttpContext.Current;
+ context.Items[_dataSlot] = new LogEventInfoBuffer(this.BufferSize, this.GrowBufferAsNeeded, this.BufferGrowLimit);
+ }
+
+ private void OnEndRequest(object sender, EventArgs args)
+ {
+ LogEventInfoBuffer buffer = GetRequestBuffer();
+ if (buffer != null)
+ {
+ LogEventInfo[] events = buffer.GetEventsAndClear();
+ if (events.Length > 0)
+ {
+ WrappedTarget.Write(events);
+ }
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Targets/Wrappers/AsyncTargetWrapper.cs b/src/NLog/Targets/Wrappers/AsyncTargetWrapper.cs
new file mode 100644
index 0000000..63c3e4a
--- /dev/null
+++ b/src/NLog/Targets/Wrappers/AsyncTargetWrapper.cs
@@ -0,0 +1,454 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Threading;
+using System.Collections;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Config;
+
+using NLog.Internal;
+
+namespace NLog.Targets.Wrappers
+{
+ /// <summary>
+ /// The action to be taken when the queue overflows
+ /// </summary>
+ public enum AsyncTargetWrapperOverflowAction
+ {
+ /// <summary>
+ /// Grow the queue.
+ /// </summary>
+ Grow,
+
+ /// <summary>
+ /// Discard the overflowing item.
+ /// </summary>
+ Discard,
+
+#if !NETCF
+ /// <summary>
+ /// Block until there's more room in the queue.
+ /// </summary>
+ Block,
+#endif
+ }
+
+ /// <summary>
+ /// A target wrapper that provides asynchronous, buffered execution of target writes.
+ /// </summary>
+ /// <remarks>
+ /// <p>
+ /// Asynchronous target wrapper allows the logger code to execute more quickly, by queueing
+ /// messages and processing them in a separate thread. You should wrap targets
+ /// that spend a non-trivial amount of time in their Write() method with asynchronous
+ /// target to speed up logging.
+ /// </p>
+ /// <p>
+ /// Because asynchronous logging is quite a common scenario, NLog supports a
+ /// shorthand notation for wrapping all targets with AsyncWrapper. Just add async="true" to
+ /// the <targets/> element in the configuration file.
+ /// </p>
+ /// <code lang="XML">
+ /// <![CDATA[
+ /// <targets async="true">
+ /// ... your targets go here ...
+ /// </targets>
+ /// ]]></code>
+ /// </remarks>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/AsyncWrapper/NLog.config" />
+ /// <p>
+ /// The above examples assume just one target and a single rule. See below for
+ /// a programmatic configuration that's equivalent to the above config file:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/AsyncWrapper/Wrapping File/Example.cs" />
+ /// </example>
+ [Target("AsyncWrapper",IsWrapper=true)]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class AsyncTargetWrapper: WrapperTargetBase
+ {
+ private int _batchSize = 100;
+ private int _timeToSleepBetweenBatches = 50;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="AsyncTargetWrapper"/>.
+ /// </summary>
+ public AsyncTargetWrapper()
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="AsyncTargetWrapper"/>
+ /// which wraps the specified target.
+ /// </summary>
+ /// <param name="wrappedTarget">The target to be wrapped.</param>
+ public AsyncTargetWrapper(Target wrappedTarget)
+ {
+ WrappedTarget = wrappedTarget;
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="AsyncTargetWrapper"/>
+ /// which wraps the specified target.
+ /// </summary>
+ /// <param name="wrappedTarget">The target to be wrapped.</param>
+ /// <param name="queueLimit">Maximum number of requests in the queue.</param>
+ /// <param name="overflowAction">The action to be taken when the queue overflows.</param>
+ public AsyncTargetWrapper(Target wrappedTarget, int queueLimit, AsyncTargetWrapperOverflowAction overflowAction)
+ {
+ WrappedTarget = wrappedTarget;
+ QueueLimit = queueLimit;
+ OverflowAction = overflowAction;
+ }
+
+ /// <summary>
+ /// Initializes the target by starting the lazy writer thread.
+ /// </summary>
+ public override void Initialize()
+ {
+ base.Initialize();
+ StartLazyWriterTimer();
+ }
+
+ /// <summary>
+ /// Closes the target by stopping the lazy writer thread.
+ /// </summary>
+ protected internal override void Close()
+ {
+ StopLazyWriterThread();
+ base.Close();
+ }
+
+ /// <summary>
+ /// The number of log events that should be processed in a batch
+ /// by the lazy writer thread.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(100)]
+ public int BatchSize
+ {
+ get { return _batchSize; }
+ set { _batchSize = value; }
+ }
+
+ /// <summary>
+ /// The time in milliseconds to sleep between batches.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(50)]
+ public int TimeToSleepBetweenBatches
+ {
+ get { return _timeToSleepBetweenBatches; }
+ set { _timeToSleepBetweenBatches = value; }
+ }
+
+ private object _inLazyWriterMonitor = new object();
+ private bool _flushAll = false;
+
+ private void LazyWriterTimerCallback(object state)
+ {
+ lock (_inLazyWriterMonitor)
+ {
+ try
+ {
+ do
+ {
+ // Console.WriteLine("q: {0}", RequestQueue.RequestCount);
+ ArrayList pendingRequests = RequestQueue.DequeueBatch(BatchSize);
+
+ try
+ {
+ if (pendingRequests.Count == 0)
+ break;
+
+ LogEventInfo[] events = (LogEventInfo[])pendingRequests.ToArray(typeof(LogEventInfo));
+ WrappedTarget.Write(events);
+ }
+ finally
+ {
+ RequestQueue.BatchProcessed(pendingRequests);
+ }
+ } while (_flushAll);
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Error in lazy writer timer procedure: {0}", ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds the log event to asynchronous queue to be processed by
+ /// the lazy writer thread.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ /// <remarks>
+ /// The <see cref="Target.PrecalculateVolatileLayouts"/> is called
+ /// to ensure that the log event can be processed in another thread.
+ /// </remarks>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ WrappedTarget.PrecalculateVolatileLayouts(logEvent);
+ RequestQueue.Enqueue(logEvent);
+ }
+
+ private Timer _lazyWriterTimer = null;
+ private AsyncRequestQueue _lazyWriterRequestQueue = new AsyncRequestQueue(10000, AsyncTargetWrapperOverflowAction.Discard);
+
+ /// <summary>
+ /// The queue of lazy writer thread requests.
+ /// </summary>
+ protected AsyncRequestQueue RequestQueue
+ {
+ get { return _lazyWriterRequestQueue; }
+ }
+
+ /// <summary>
+ /// The action to be taken when the lazy writer thread request queue count
+ /// exceeds the set limit.
+ /// </summary>
+ [System.ComponentModel.DefaultValue("Discard")]
+ public AsyncTargetWrapperOverflowAction OverflowAction
+ {
+ get { return _lazyWriterRequestQueue.OnOverflow; }
+ set { _lazyWriterRequestQueue.OnOverflow = value; }
+ }
+
+ /// <summary>
+ /// The limit on the number of requests in the lazy writer thread request queue.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(10000)]
+ public int QueueLimit
+ {
+ get { return _lazyWriterRequestQueue.RequestLimit; }
+ set { _lazyWriterRequestQueue.RequestLimit = value; }
+ }
+
+ /// <summary>
+ /// Starts the lazy writer thread which periodically writes
+ /// queued log messages.
+ /// </summary>
+ protected virtual void StartLazyWriterTimer()
+ {
+ _lazyWriterRequestQueue.Clear();
+ Internal.InternalLogger.Debug("Starting lazy writer timer...");
+ _lazyWriterTimer = new Timer(new TimerCallback(LazyWriterTimerCallback), null, 0, this.TimeToSleepBetweenBatches);
+ }
+
+ /// <summary>
+ /// Starts the lazy writer thread.
+ /// </summary>
+ protected virtual void StopLazyWriterThread()
+ {
+ if (_lazyWriterTimer == null)
+ return;
+
+ Flush();
+ _lazyWriterTimer.Change(0, 0);
+ _lazyWriterTimer.Dispose();
+ _lazyWriterTimer = null;
+
+ _lazyWriterRequestQueue.Clear();
+ }
+
+ /// <summary>
+ /// Waits for the lazy writer thread to finish writing messages.
+ /// </summary>
+ public override void Flush(TimeSpan timeout)
+ {
+ _lazyWriterTimer.Change(Timeout.Infinite, Timeout.Infinite);
+ lock (_inLazyWriterMonitor)
+ {
+ _flushAll = true;
+ LazyWriterTimerCallback(null);
+ }
+ _lazyWriterTimer.Change(TimeToSleepBetweenBatches, TimeToSleepBetweenBatches);
+ }
+
+ /// <summary>
+ /// Asynchronous request queue
+ /// </summary>
+ public class AsyncRequestQueue
+ {
+ private Queue _queue = new Queue();
+ private int _batchedItems = 0;
+ private AsyncTargetWrapperOverflowAction _overflowAction = AsyncTargetWrapperOverflowAction.Discard;
+ private int _requestLimit = 10000;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="AsyncRequestQueue"/> and
+ /// sets the request limit and overflow action.
+ /// </summary>
+ /// <param name="requestLimit">Request limit.</param>
+ /// <param name="overflowAction">The overflow action.</param>
+ public AsyncRequestQueue(int requestLimit, AsyncTargetWrapperOverflowAction overflowAction)
+ {
+ _requestLimit = requestLimit;
+ _overflowAction = overflowAction;
+ }
+
+ /// <summary>
+ /// The request limit.
+ /// </summary>
+ public int RequestLimit
+ {
+ get { return _requestLimit; }
+ set { _requestLimit = value; }
+ }
+
+ /// <summary>
+ /// Action to be taken when there's no more room in
+ /// the queue and another request is enqueued.
+ /// </summary>
+ public AsyncTargetWrapperOverflowAction OnOverflow
+ {
+ get { return _overflowAction; }
+ set { _overflowAction = value; }
+ }
+
+ /// <summary>
+ /// Enqueues another item. If the queue is overflown the appropriate
+ /// action is taken as specified by <see cref="OnOverflow"/>.
+ /// </summary>
+ /// <param name="o">The item to be queued.</param>
+ public void Enqueue(object o)
+ {
+ lock (this)
+ {
+ if (_queue.Count >= RequestLimit)
+ {
+ switch (OnOverflow)
+ {
+ case AsyncTargetWrapperOverflowAction.Discard:
+ return;
+
+ case AsyncTargetWrapperOverflowAction.Grow:
+ break;
+
+#if !NETCF
+ case AsyncTargetWrapperOverflowAction.Block:
+ while (_queue.Count >= RequestLimit)
+ {
+ InternalLogger.Debug("Blocking...");
+ if (System.Threading.Monitor.Wait(this))
+ {
+ InternalLogger.Debug("Entered critical section.");
+ }
+ else
+ {
+ InternalLogger.Debug("Failed to enter critical section.");
+ }
+ }
+ InternalLogger.Debug("Limit ok.");
+ break;
+#endif
+ }
+ }
+ _queue.Enqueue(o);
+ }
+ }
+
+ /// <summary>
+ /// Dequeues a maximum of <c>count</c> items from the queue
+ /// and adds returns the <see cref="ArrayList"/> containing them.
+ /// </summary>
+ /// <param name="count">Maximum number of items to be dequeued.</param>
+ public ArrayList DequeueBatch(int count)
+ {
+ ArrayList target = new ArrayList();
+ lock (this)
+ {
+ for (int i = 0; i < count; ++i)
+ {
+ if (_queue.Count <= 0)
+ break;
+
+ object o = _queue.Dequeue();
+
+ target.Add(o);
+ }
+#if !NETCF
+ if (OnOverflow == AsyncTargetWrapperOverflowAction.Block)
+ System.Threading.Monitor.PulseAll(this);
+#endif
+ }
+ _batchedItems = target.Count;
+ return target;
+ }
+
+ /// <summary>
+ /// Notifies the queue that the request batch has been processed.
+ /// </summary>
+ /// <param name="batch">The batch.</param>
+ public void BatchProcessed(ArrayList batch)
+ {
+ _batchedItems = 0;
+ }
+
+ /// <summary>
+ /// Clears the queue.
+ /// </summary>
+ public void Clear()
+ {
+ lock (this)
+ {
+ _queue.Clear();
+ }
+ }
+
+ /// <summary>
+ /// Number of requests currently in the queue.
+ /// </summary>
+ public int RequestCount
+ {
+ get { return _queue.Count; }
+ }
+
+ /// <summary>
+ /// Number of requests currently being processed (in the queue + batched)
+ /// </summary>
+ public int UnprocessedRequestCount
+ {
+ get { return _queue.Count + _batchedItems; }
+ }
+ }
+
+ }
+}
diff --git a/src/NLog/Targets/Wrappers/AutoFlushTargetWrapper.cs b/src/NLog/Targets/Wrappers/AutoFlushTargetWrapper.cs
new file mode 100644
index 0000000..6ee8fbf
--- /dev/null
+++ b/src/NLog/Targets/Wrappers/AutoFlushTargetWrapper.cs
@@ -0,0 +1,94 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+
+using NLog.Config;
+
+namespace NLog.Targets.Wrappers
+{
+ /// <summary>
+ /// A target wrapper that causes a flush after each write on a wrapped target.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/AutoFlushWrapper/NLog.config" />
+ /// <p>
+ /// The above examples assume just one target and a single rule. See below for
+ /// a programmatic configuration that's equivalent to the above config file:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/AutoFlushWrapper/Simple/Example.cs" />
+ /// </example>
+ [Target("AutoFlushWrapper", IgnoresLayout = true, IsWrapper = true)]
+ public class AutoFlushTargetWrapper: WrapperTargetBase
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="AutoFlushTargetWrapper"/>.
+ /// </summary>
+ public AutoFlushTargetWrapper()
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="AutoFlushTargetWrapper"/>
+ /// and initializes the <see cref="WrapperTargetBase.WrappedTarget"/> to the specified <see cref="Target"/> value.
+ /// </summary>
+ public AutoFlushTargetWrapper(Target writeTo)
+ {
+ WrappedTarget = writeTo;
+ }
+
+ /// <summary>
+ /// Forwards the call to the <see cref="WrapperTargetBase.WrappedTarget"/>.Write()
+ /// and calls <see cref="Target.Flush()"/> on it.
+ /// </summary>
+ /// <param name="logEvent"></param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ WrappedTarget.Write(logEvent);
+ WrappedTarget.Flush();
+ }
+ }
+}
diff --git a/src/NLog/Targets/Wrappers/BufferingTargetWrapper.cs b/src/NLog/Targets/Wrappers/BufferingTargetWrapper.cs
new file mode 100644
index 0000000..db5e4e2
--- /dev/null
+++ b/src/NLog/Targets/Wrappers/BufferingTargetWrapper.cs
@@ -0,0 +1,206 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+
+using NLog.Config;
+using System.Threading;
+
+namespace NLog.Targets.Wrappers
+{
+ /// <summary>
+ /// A target that buffers log events and sends them in batches to the wrapped target.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/BufferingWrapper/NLog.config" />
+ /// <p>
+ /// The above examples assume just one target and a single rule. See below for
+ /// a programmatic configuration that's equivalent to the above config file:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/BufferingWrapper/Simple/Example.cs" />
+ /// </example>
+ [Target("BufferingWrapper", IgnoresLayout = true, IsWrapper = true)]
+ public class BufferingTargetWrapper: WrapperTargetBase
+ {
+ private LogEventInfoBuffer _buffer;
+ private Timer _flushTimer;
+ private int _flushTimeout = -1;
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="BufferingTargetWrapper"/> and initializes <see cref="BufferSize"/> to 100.
+ /// </summary>
+ public BufferingTargetWrapper()
+ {
+ BufferSize = 100;
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="BufferingTargetWrapper"/>, initializes <see cref="BufferSize"/> to 100 and
+ /// sets the <see cref="WrapperTargetBase.WrappedTarget"/> to the specified value.
+ /// </summary>
+ public BufferingTargetWrapper(Target writeTo) : this(writeTo, 100)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="BufferingTargetWrapper"/>, initializes <see cref="BufferSize"/> and
+ /// the <see cref="WrapperTargetBase.WrappedTarget"/> to the specified values.
+ /// </summary>
+ public BufferingTargetWrapper(Target writeTo, int bufferSize)
+ {
+ WrappedTarget = writeTo;
+ BufferSize = bufferSize;
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="BufferingTargetWrapper"/>,
+ /// initializes <see cref="BufferSize"/>, <see cref="WrapperTargetBase.WrappedTarget"/>
+ /// and <see cref="FlushTimeout"/> to the specified values.
+ /// </summary>
+ public BufferingTargetWrapper(Target writeTo, int bufferSize, int flushTimeout)
+ {
+ WrappedTarget = writeTo;
+ BufferSize = bufferSize;
+ FlushTimeout = flushTimeout;
+ }
+
+ /// <summary>
+ /// Number of log events to be buffered.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(100)]
+ public int BufferSize
+ {
+ get { return _buffer.Size; }
+ set { _buffer = new LogEventInfoBuffer(value, false, 0); }
+ }
+
+ /// <summary>
+ /// Flush the contents of buffer if there's no write in the specified period of time
+ /// (milliseconds). Use -1 to disable timed flushes.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(-1)]
+ public int FlushTimeout
+ {
+ get { return _flushTimeout; }
+ set { _flushTimeout = value; }
+ }
+
+ /// <summary>
+ /// Initializes the target.
+ /// </summary>
+ public override void Initialize()
+ {
+ base.Initialize();
+ _flushTimer = new Timer(new TimerCallback(this.FlushCallback), null, -1, -1);
+ }
+
+ /// <summary>
+ /// Adds the specified log event to the buffer and flushes
+ /// the buffer in case the buffer gets full.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ lock (this)
+ {
+ WrappedTarget.PrecalculateVolatileLayouts(logEvent);
+ int count = _buffer.Append(logEvent);
+ if (count >= BufferSize)
+ {
+ LogEventInfo[] events = _buffer.GetEventsAndClear();
+ WrappedTarget.Write(events);
+ }
+ else
+ {
+ if (FlushTimeout > 0 && _flushTimer != null)
+ {
+ _flushTimer.Change(FlushTimeout, -1);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Flushes pending events in the buffer (if any).
+ /// </summary>
+ public override void Flush(TimeSpan timeout)
+ {
+ base.Flush (timeout);
+
+ lock (this)
+ {
+ LogEventInfo[] events = _buffer.GetEventsAndClear();
+ if (events.Length > 0)
+ {
+ WrappedTarget.Write(events);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Closes the target by flushing pending events in the buffer (if any).
+ /// </summary>
+ protected internal override void Close()
+ {
+ Flush(TimeSpan.FromSeconds(3));
+ base.Close ();
+ _flushTimer.Dispose();
+ _flushTimer = null;
+ }
+
+ void FlushCallback(object state)
+ {
+ lock (this)
+ {
+ LogEventInfo[] events = _buffer.GetEventsAndClear();
+ if (events.Length > 0)
+ {
+ WrappedTarget.Write(events);
+ }
+ }
+ }
+ }
+}
diff --git a/src/NLog/Targets/Wrappers/FilteringRule.cs b/src/NLog/Targets/Wrappers/FilteringRule.cs
new file mode 100644
index 0000000..dd48ad4
--- /dev/null
+++ b/src/NLog/Targets/Wrappers/FilteringRule.cs
@@ -0,0 +1,100 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Diagnostics;
+using System.Reflection;
+using System.Data;
+using System.Collections;
+
+using NLog.Internal;
+using NLog.Config;
+using NLog.Conditions;
+
+namespace NLog.Targets.Wrappers
+{
+ /// <summary>
+ /// Filtering rule for <see cref="PostFilteringTargetWrapper"/>.
+ /// </summary>
+ public class FilteringRule
+ {
+ private ConditionExpression _exists;
+ private ConditionExpression _filter;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="FilteringRule"/>.
+ /// </summary>
+ public FilteringRule() {}
+
+ /// <summary>
+ /// Condition to be tested.
+ /// </summary>
+ [RequiredParameter]
+ [AcceptsCondition]
+ public string Exists
+ {
+ get { return _exists.ToString(); }
+ set { _exists = ConditionParser.ParseExpression(value); }
+ }
+
+ /// <summary>
+ /// Resulting filter to be applied when the condition matches.
+ /// </summary>
+ [RequiredParameter]
+ [AcceptsCondition]
+ public string Filter
+ {
+ get { return _filter.ToString(); }
+ set { _filter = ConditionParser.ParseExpression(value); }
+ }
+
+ /// <summary>
+ /// Parsed Filter condition.
+ /// </summary>
+ public ConditionExpression FilterCondition
+ {
+ get { return _filter; }
+ set { _filter = value; }
+ }
+
+ /// <summary>
+ /// Parsed Exists condition.
+ /// </summary>
+ public ConditionExpression ExistsCondition
+ {
+ get { return _exists; }
+ set { _exists = value; }
+ }
+ }
+}
diff --git a/src/NLog/Targets/Wrappers/FilteringRuleCollection.cs b/src/NLog/Targets/Wrappers/FilteringRuleCollection.cs
new file mode 100644
index 0000000..85ee1a9
--- /dev/null
+++ b/src/NLog/Targets/Wrappers/FilteringRuleCollection.cs
@@ -0,0 +1,249 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Text;
+using System.Diagnostics;
+using System.Reflection;
+using System.Data;
+using System.Collections;
+
+using NLog.Internal;
+using NLog.Config;
+
+namespace NLog.Targets.Wrappers
+{
+ // CLOVER:OFF
+ /// <summary>
+ /// A collection of elements of type FilteringRule
+ /// </summary>
+ public class FilteringRuleCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the FilteringRuleCollection class.
+ /// </summary>
+ public FilteringRuleCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the FilteringRuleCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new FilteringRuleCollection.
+ /// </param>
+ public FilteringRuleCollection(FilteringRule[]items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the FilteringRuleCollection class, containing elements
+ /// copied from another instance of FilteringRuleCollection
+ /// </summary>
+ /// <param name="items">
+ /// The FilteringRuleCollection whose elements are to be added to the new FilteringRuleCollection.
+ /// </param>
+ public FilteringRuleCollection(FilteringRuleCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this FilteringRuleCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this FilteringRuleCollection.
+ /// </param>
+ public virtual void AddRange(FilteringRule[]items)
+ {
+ foreach (FilteringRule item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another FilteringRuleCollection to the end of this FilteringRuleCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The FilteringRuleCollection whose elements are to be added to the end of this FilteringRuleCollection.
+ /// </param>
+ public virtual void AddRange(FilteringRuleCollection items)
+ {
+ foreach (FilteringRule item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type FilteringRule to the end of this FilteringRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The FilteringRule to be added to the end of this FilteringRuleCollection.
+ /// </param>
+ public virtual void Add(FilteringRule value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic FilteringRule value is in this FilteringRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The FilteringRule value to locate in this FilteringRuleCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this FilteringRuleCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(FilteringRule value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this FilteringRuleCollection
+ /// </summary>
+ /// <param name="value">
+ /// The FilteringRule value to locate in the FilteringRuleCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(FilteringRule value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the FilteringRuleCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the FilteringRule is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The FilteringRule to insert.
+ /// </param>
+ public virtual void Insert(int index, FilteringRule value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the FilteringRule at the given index in this FilteringRuleCollection.
+ /// </summary>
+ public virtual FilteringRule this[int index]
+ {
+ get { return (FilteringRule)this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific FilteringRule from this FilteringRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The FilteringRule value to remove from this FilteringRuleCollection.
+ /// </param>
+ public virtual void Remove(FilteringRule value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by FilteringRuleCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(FilteringRuleCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public FilteringRule Current
+ {
+ get { return (FilteringRule)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (FilteringRule)(this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this FilteringRuleCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual FilteringRuleCollection.Enumerator GetEnumerator()
+ {
+ return new FilteringRuleCollection.Enumerator(this);
+ }
+ }
+}
diff --git a/src/NLog/Targets/Wrappers/FilteringWrapper.cs b/src/NLog/Targets/Wrappers/FilteringWrapper.cs
new file mode 100644
index 0000000..1af838b
--- /dev/null
+++ b/src/NLog/Targets/Wrappers/FilteringWrapper.cs
@@ -0,0 +1,125 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+
+using NLog.Config;
+using NLog.Conditions;
+
+namespace NLog.Targets.Wrappers
+{
+ /// <summary>
+ /// A target wrapper that filters log entries based on a condition.
+ /// </summary>
+ /// <example>
+ /// <p>This example causes the messages not contains the string '1' to be ignored.</p>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/FilteringWrapper/NLog.config" />
+ /// <p>
+ /// The above examples assume just one target and a single rule. See below for
+ /// a programmatic configuration that's equivalent to the above config file:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/FilteringWrapper/Simple/Example.cs" />
+ /// </example>
+ [Target("FilteringWrapper", IgnoresLayout = true, IsWrapper = true)]
+ public class FilteringTargetWrapper: WrapperTargetBase
+ {
+ private ConditionExpression _condition;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="FilteringTargetWrapper"/>.
+ /// </summary>
+ public FilteringTargetWrapper()
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="FilteringTargetWrapper"/> and
+ /// initializes the <see cref="WrapperTargetBase.WrappedTarget"/> and
+ /// <see cref="Condition"/> properties.
+ /// </summary>
+ public FilteringTargetWrapper(Target writeTo, string condition)
+ {
+ WrappedTarget = writeTo;
+ Condition = condition;
+ }
+
+ /// <summary>
+ /// Condition expression. Log events who meet this condition will be forwarded
+ /// to the wrapped target.
+ /// </summary>
+ [RequiredParameter]
+ [AcceptsCondition]
+ public string Condition
+ {
+ get { return _condition.ToString(); }
+ set { _condition = ConditionParser.ParseExpression(value); }
+ }
+
+ /// <summary>
+ /// Checks the condition against the passed log event.
+ /// If the condition is met, the log event is forwarded to
+ /// the wrapped target.
+ /// </summary>
+ /// <param name="logEvent">Log event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ object v = _condition.Evaluate(logEvent);
+ if (v != null && v is bool && (bool)v)
+ WrappedTarget.Write(logEvent);
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ base.PopulateLayouts(layouts);
+ _condition.PopulateLayouts(layouts);
+ }
+
+ }
+}
diff --git a/src/NLog/Targets/Wrappers/ImpersonatingWrapper.cs b/src/NLog/Targets/Wrappers/ImpersonatingWrapper.cs
new file mode 100644
index 0000000..1bf8161
--- /dev/null
+++ b/src/NLog/Targets/Wrappers/ImpersonatingWrapper.cs
@@ -0,0 +1,390 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Config;
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+using System.Runtime.InteropServices;
+using System.Security.Principal;
+using System.ComponentModel;
+
+namespace NLog.Targets.Wrappers
+{
+ /// <summary>
+ /// A target wrapper that impersonates another user for the duration of the write.
+ /// </summary>
+ [Target("ImpersonatingWrapper", IgnoresLayout = true, IsWrapper = true)]
+ [SupportedRuntime(OS = RuntimeOS.WindowsNT)]
+ public class ImpersonatingTargetWrapper : WrapperTargetBase
+ {
+ private string _username;
+ private string _password;
+ private string _domain = ".";
+ private WindowsIdentity _newIdentity;
+ private SecurityLogonType _logonType = SecurityLogonType.Interactive;
+ private LogonProviderType _logonProvider = LogonProviderType.Default;
+ private SecurityImpersonationLevel _impersonationLevel = SecurityImpersonationLevel.Impersonation;
+ private IntPtr _existingTokenHandle = IntPtr.Zero;
+ private IntPtr _duplicateTokenHandle = IntPtr.Zero;
+ private bool _revertToSelf = false;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ImpersonatingTargetWrapper"/>.
+ /// </summary>
+ public ImpersonatingTargetWrapper()
+ {
+ }
+
+ /// <summary>
+ /// Username to change context to
+ /// </summary>
+ public string Username
+ {
+ get { return _username; }
+ set { _username = value; }
+ }
+
+ /// <summary>
+ /// Password
+ /// </summary>
+ public string Password
+ {
+ get { return _password; }
+ set { _password = value; }
+ }
+
+ /// <summary>
+ /// Windows domain name to change context to.
+ /// </summary>
+ [DefaultValue(".")]
+ public string Domain
+ {
+ get { return _domain; }
+ set { _domain = value; }
+ }
+
+ /// <summary>
+ /// Logon Type.
+ /// </summary>
+ public SecurityLogonType LogonType
+ {
+ get { return _logonType; }
+ set { _logonType = value; }
+ }
+
+ /// <summary>
+ /// Logon Provider.
+ /// </summary>
+ public LogonProviderType LogonProvider
+ {
+ get { return _logonProvider; }
+ set { _logonProvider = value; }
+ }
+
+ /// <summary>
+ /// Impersonation level.
+ /// </summary>
+ public SecurityImpersonationLevel ImpersonationLevel
+ {
+ get { return _impersonationLevel; }
+ set { _impersonationLevel = value; }
+ }
+
+ /// <summary>
+ /// Revert to the credentials of the process instead of impersonating another user.
+ /// </summary>
+ [DefaultValue(false)]
+ public bool RevertToSelf
+ {
+ get { return _revertToSelf; }
+ set { _revertToSelf = value; }
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ImpersonatingTargetWrapper"/>
+ /// and initializes the <see cref="WrapperTargetBase.WrappedTarget"/> to the specified <see cref="Target"/> value.
+ /// </summary>
+ public ImpersonatingTargetWrapper(Target writeTo)
+ {
+ WrappedTarget = writeTo;
+ }
+
+ /// <summary>
+ /// Changes the security context, forwards the call to the <see cref="WrapperTargetBase.WrappedTarget"/>.Write()
+ /// and switches the context back to original.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ using (DoImpersonate())
+ {
+ WrappedTarget.Write(logEvent);
+ }
+ }
+
+ /// <summary>
+ /// Changes the security context, forwards the call to the <see cref="WrapperTargetBase.WrappedTarget"/>.Write()
+ /// and switches the context back to original.
+ /// </summary>
+ /// <param name="logEvents">Log events.</param>
+ protected internal override void Write(LogEventInfo[] logEvents)
+ {
+ using (DoImpersonate())
+ {
+ WrappedTarget.Write(logEvents);
+ }
+ }
+
+ /// <summary>
+ /// Initializes the impersonation context.
+ /// </summary>
+ public override void Initialize()
+ {
+ if (!RevertToSelf)
+ _newIdentity = CreateWindowsIdentity();
+ using (DoImpersonate())
+ {
+ base.Initialize();
+ }
+ }
+
+ /// <summary>
+ /// Closes the impersonation context.
+ /// </summary>
+ protected internal override void Close()
+ {
+ using (DoImpersonate())
+ {
+ base.Close();
+ }
+ if (_existingTokenHandle != IntPtr.Zero)
+ {
+ CloseHandle(_existingTokenHandle);
+ _existingTokenHandle = IntPtr.Zero;
+ }
+ if (_duplicateTokenHandle != IntPtr.Zero)
+ {
+ CloseHandle(_duplicateTokenHandle);
+ _duplicateTokenHandle = IntPtr.Zero;
+ }
+ }
+
+ private IDisposable DoImpersonate()
+ {
+ if (RevertToSelf)
+ return new ContextReverter(WindowsIdentity.Impersonate(IntPtr.Zero));
+
+ if (_newIdentity != null)
+ return new ContextReverter(_newIdentity.Impersonate());
+
+ return null;
+ }
+
+ /// <summary>
+ /// Impersonation level.
+ /// </summary>
+ public enum SecurityImpersonationLevel
+ {
+ /// <summary>
+ /// Anonymous
+ /// </summary>
+ Anonymous = 0,
+
+ /// <summary>
+ /// Identification
+ /// </summary>
+ Identification = 1,
+
+ /// <summary>
+ /// Impersonation
+ /// </summary>
+ Impersonation = 2,
+
+ /// <summary>
+ /// Delegation
+ /// </summary>
+ Delegation = 3
+ }
+
+ /// <summary>
+ /// Logon type.
+ /// </summary>
+ public enum SecurityLogonType : int
+ {
+ /// <summary>
+ /// Interactive Logon
+ /// </summary>
+ /// <remarks>
+ /// This logon type is intended for users who will be interactively using the computer, such as a user being logged on
+ /// by a terminal server, remote shell, or similar process.
+ /// This logon type has the additional expense of caching logon information for disconnected operations;
+ /// therefore, it is inappropriate for some client/server applications,
+ /// such as a mail server.
+ /// </remarks>
+ Interactive = 2,
+
+ /// <summary>
+ /// Network Logon
+ /// </summary>
+ /// <remarks>
+ /// This logon type is intended for high performance servers to authenticate plaintext passwords.
+ /// The LogonUser function does not cache credentials for this logon type.
+ /// </remarks>
+ Network = 3,
+
+ /// <summary>
+ /// Batch Logon
+ /// </summary>
+ /// <remarks>
+ /// This logon type is intended for batch servers, where processes may be executing on behalf of a user without
+ /// their direct intervention. This type is also for higher performance servers that process many plaintext
+ /// authentication attempts at a time, such as mail or Web servers.
+ /// The LogonUser function does not cache credentials for this logon type.
+ /// </remarks>
+ Batch = 4,
+
+ /// <summary>
+ /// Logon as a Service
+ /// </summary>
+ /// <remarks>
+ /// Indicates a service-type logon. The account provided must have the service privilege enabled.
+ /// </remarks>
+ Service = 5,
+
+ /// <summary>
+ /// Network Clear Text Logon
+ /// </summary>
+ /// <remarks>
+ /// This logon type preserves the name and password in the authentication package, which allows the server to make
+ /// connections to other network servers while impersonating the client. A server can accept plaintext credentials
+ /// from a client, call LogonUser, verify that the user can access the system across the network, and still
+ /// communicate with other servers.
+ /// NOTE: Windows NT: This value is not supported.
+ /// </remarks>
+ NetworkClearText = 8,
+
+ /// <summary>
+ /// New Network Credentials
+ /// </summary>
+ /// <remarks>
+ /// This logon type allows the caller to clone its current token and specify new credentials for outbound connections.
+ /// The new logon session has the same local identifier but uses different credentials for other network connections.
+ /// NOTE: This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider.
+ /// NOTE: Windows NT: This value is not supported.
+ /// </remarks>
+ NewCredentials = 9,
+ }
+
+ /// <summary>
+ /// Logon provider.
+ ///
+ /// </summary>
+ public enum LogonProviderType : int
+ {
+ /// <summary>
+ /// Use the standard logon provider for the system.
+ /// </summary>
+ /// <remarks>
+ /// The default security provider is negotiate, unless you pass NULL for the domain name and the user name
+ /// is not in UPN format. In this case, the default provider is NTLM.
+ /// NOTE: Windows 2000/NT: The default security provider is NTLM.
+ /// </remarks>
+ Default = 0,
+ }
+
+ // obtains user token
+ [DllImport("advapi32.dll", SetLastError = true)]
+ private static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
+
+ // closes open handes returned by LogonUser
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
+ private extern static bool CloseHandle(IntPtr handle);
+
+ // creates duplicate token handle
+ [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ private extern static bool DuplicateToken(IntPtr existingTokenHandle, int impersonationLevel, out IntPtr duplicateTokenHandle);
+
+ //
+ // adapted from:
+ // http://www.codeproject.com/csharp/cpimpersonation1.asp
+ //
+ private WindowsIdentity CreateWindowsIdentity()
+ {
+ // initialize tokens
+ _existingTokenHandle = IntPtr.Zero;
+ _duplicateTokenHandle = IntPtr.Zero;
+
+ if (!LogonUser(Username, Domain, Password,
+ (int)_logonType, (int)_logonProvider,
+ out _existingTokenHandle))
+ Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
+
+ if (!DuplicateToken(_existingTokenHandle, (int)_impersonationLevel, out _duplicateTokenHandle))
+ {
+ CloseHandle(_existingTokenHandle);
+ _existingTokenHandle = IntPtr.Zero;
+ Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
+ }
+
+ // create new identity using new primary token
+ return new WindowsIdentity(_duplicateTokenHandle);
+ }
+
+ internal class ContextReverter : IDisposable
+ {
+ private WindowsImpersonationContext _wic;
+
+ public ContextReverter(WindowsImpersonationContext wic)
+ {
+ _wic = wic;
+ }
+
+ public void Dispose()
+ {
+ _wic.Undo();
+ }
+ }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/NLog/Targets/Wrappers/PostFilteringWrapper.cs b/src/NLog/Targets/Wrappers/PostFilteringWrapper.cs
new file mode 100644
index 0000000..21df0c0
--- /dev/null
+++ b/src/NLog/Targets/Wrappers/PostFilteringWrapper.cs
@@ -0,0 +1,196 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Collections;
+using System.Diagnostics;
+
+using NLog.Internal;
+using NLog.Config;
+using NLog.Conditions;
+
+namespace NLog.Targets.Wrappers
+{
+ /// <summary>
+ /// A target wrapper that filters buffered log entries based on a set of conditions
+ /// that are evaluated on all events.
+ /// </summary>
+ /// <remarks>
+ /// PostFilteringWrapper must be used with some type of buffering target or wrapper, such as
+ /// AsyncTargetWrapper, BufferingWrapper or ASPNetBufferingWrapper.
+ /// </remarks>
+ /// <example>
+ /// <p>
+ /// This example works like this. If there are no Warn,Error or Fatal messages in the buffer
+ /// only Info messages are written to the file, but if there are any warnings or errors,
+ /// the output includes detailed trace (levels >= Debug). You can plug in a different type
+ /// of buffering wrapper (such as ASPNetBufferingWrapper) to achieve different
+ /// functionality.
+ /// </p>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/PostFilteringWrapper/NLog.config" />
+ /// <p>
+ /// The above examples assume just one target and a single rule. See below for
+ /// a programmatic configuration that's equivalent to the above config file:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/PostFilteringWrapper/Simple/Example.cs" />
+ /// </example>
+ [Target("PostFilteringWrapper", IgnoresLayout = true, IsWrapper = true)]
+ public class PostFilteringTargetWrapper: WrapperTargetBase
+ {
+ private ConditionExpression _defaultFilter;
+ private FilteringRuleCollection _rules = new FilteringRuleCollection();
+
+ /// <summary>
+ /// Creates a new instance of <see cref="PostFilteringTargetWrapper"/>.
+ /// </summary>
+ public PostFilteringTargetWrapper()
+ {
+ }
+
+ /// <summary>
+ /// Default filter to be applied when no specific rule matches.
+ /// </summary>
+ public string DefaultFilter
+ {
+ get { return _defaultFilter.ToString(); }
+ set { _defaultFilter = ConditionParser.ParseExpression(value); }
+ }
+
+ /// <summary>
+ /// Collection of filtering rules. The rules are processed top-down
+ /// and the first rule that matches determines the filtering condition to
+ /// be applied to log events.
+ /// </summary>
+ [ArrayParameter(typeof(FilteringRule), "when")]
+ public FilteringRuleCollection Rules
+ {
+ get { return _rules; }
+ }
+
+
+ /// <summary>
+ /// Evaluates all filtering rules to find the first one that matches.
+ /// The matching rule determines the filtering condition to be applied
+ /// to all items in a buffer. If no condition matches, default filter
+ /// is applied to the array of log events.
+ /// </summary>
+ /// <param name="logEvents">Array of log events to be post-filtered.</param>
+ protected internal override void Write(LogEventInfo[] logEvents)
+ {
+ ConditionExpression resultFilter = null;
+
+ if (InternalLogger.IsTraceEnabled)
+ {
+ InternalLogger.Trace("Input: {0} events", logEvents.Length);
+ }
+
+ // evaluate all the rules to get the filtering condition
+
+ for (int i = 0; i < logEvents.Length; ++i)
+ {
+ for (int j = 0; j < _rules.Count; ++j)
+ {
+ object v = _rules[j].ExistsCondition.Evaluate(logEvents[i]);
+
+ if (v is bool && (bool)v)
+ {
+ if (InternalLogger.IsTraceEnabled)
+ InternalLogger.Trace("Rule matched: {0}", _rules[j].ExistsCondition);
+ resultFilter = _rules[j].FilterCondition;
+ break;
+ }
+ }
+ if (resultFilter != null)
+ break;
+ }
+
+ if (resultFilter == null)
+ resultFilter = _defaultFilter;
+
+ if (InternalLogger.IsTraceEnabled)
+ InternalLogger.Trace("Filter to apply: {0}", resultFilter);
+
+ // apply the condition to the buffer
+
+ ArrayList resultBuffer = new ArrayList();
+
+ for (int i = 0; i < logEvents.Length; ++i)
+ {
+ object v = resultFilter.Evaluate(logEvents[i]);
+ if (v is bool && (bool)v)
+ resultBuffer.Add(logEvents[i]);
+ }
+
+ if (InternalLogger.IsTraceEnabled)
+ InternalLogger.Trace("After filtering: {0} events", resultBuffer.Count);
+
+ if (resultBuffer.Count > 0)
+ {
+ WrappedTarget.Write((LogEventInfo[])resultBuffer.ToArray(typeof(LogEventInfo)));
+ }
+ }
+
+ /// <summary>
+ /// Processes a single log event. Not very useful for this post-filtering
+ /// wrapper.
+ /// </summary>
+ /// <param name="logEvent">Log event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ Write(new LogEventInfo[] { logEvent });
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ base.PopulateLayouts(layouts);
+ foreach (FilteringRule fr in Rules)
+ {
+ fr.FilterCondition.PopulateLayouts(layouts);
+ fr.ExistsCondition.PopulateLayouts(layouts);
+ }
+ _defaultFilter.PopulateLayouts(layouts);
+ }
+ }
+}
diff --git a/src/NLog/Targets/Wrappers/RepeatTargetWrapper.cs b/src/NLog/Targets/Wrappers/RepeatTargetWrapper.cs
new file mode 100644
index 0000000..7bef561
--- /dev/null
+++ b/src/NLog/Targets/Wrappers/RepeatTargetWrapper.cs
@@ -0,0 +1,129 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+
+using NLog.Config;
+
+namespace NLog.Targets.Wrappers
+{
+ /// <summary>
+ /// A target wrapper that repeats each log event the specified number of times.
+ /// </summary>
+ /// <example>
+ /// <p>This example causes each log message to be repeated 3 times.</p>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/RepeatingWrapper/NLog.config" />
+ /// <p>
+ /// The above examples assume just one target and a single rule. See below for
+ /// a programmatic configuration that's equivalent to the above config file:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/RepeatingWrapper/Simple/Example.cs" />
+ /// </example>
+ [Target("RepeatingWrapper", IgnoresLayout = true, IsWrapper = true)]
+ public class RepeatingTargetWrapper: WrapperTargetBase
+ {
+ private int _repeatCount = 3;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="RepeatingTargetWrapper"/>.
+ /// </summary>
+ public RepeatingTargetWrapper()
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="RepeatingTargetWrapper"/>,
+ /// initializes the <see cref="WrapperTargetBase.WrappedTarget"/> to the specified <see cref="Target"/> value and
+ /// sets the <see cref="RepeatCount"/>,
+ /// </summary>
+ public RepeatingTargetWrapper(Target writeTo, int repeatCount)
+ {
+ WrappedTarget = writeTo;
+ RepeatCount = repeatCount;
+ }
+
+ /// <summary>
+ /// The number of times to repeat each log message.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(3)]
+ public int RepeatCount
+ {
+ get { return _repeatCount; }
+ set { _repeatCount = value; }
+ }
+
+ /// <summary>
+ /// Forwards the log message to the <see cref="WrapperTargetBase.WrappedTarget"/> by calling the <see cref="Target.Write(LogEventInfo)"/> method <see cref="RepeatCount"/> times.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ for (int i = 0; i < RepeatCount; ++i)
+ {
+ WrappedTarget.Write(logEvent);
+ }
+ }
+
+ /// <summary>
+ /// Forwards the array of log events to the <see cref="WrapperTargetBase.WrappedTarget"/> by calling the <see cref="Target.Write(LogEventInfo[])"/> method <see cref="RepeatCount"/> times.
+ /// </summary>
+ /// <param name="logEvents">The array of log events.</param>
+ protected internal override void Write(LogEventInfo[] logEvents)
+ {
+ LogEventInfo[] newEvents = new LogEventInfo[logEvents.Length * RepeatCount];
+ int pos = 0;
+
+ for (int i = 0; i < logEvents.Length; ++i)
+ {
+ for (int j = 0; j < RepeatCount; ++j)
+ {
+ newEvents[pos++] = logEvents[i];
+ }
+ }
+ WrappedTarget.Write(newEvents);
+ }
+ }
+}
diff --git a/src/NLog/Targets/Wrappers/RetryTargetWrapper.cs b/src/NLog/Targets/Wrappers/RetryTargetWrapper.cs
new file mode 100644
index 0000000..8bbc58f
--- /dev/null
+++ b/src/NLog/Targets/Wrappers/RetryTargetWrapper.cs
@@ -0,0 +1,138 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog.Internal;
+using System.Net;
+using System.Net.Sockets;
+
+using NLog.Config;
+
+namespace NLog.Targets.Wrappers
+{
+ /// <summary>
+ /// A target wrapper that causes retries on wrapped target errors.
+ /// </summary>
+ /// <example>
+ /// <p>This example causes each write attempt to be repeated 3 times,
+ /// sleeping 1 second between attempts if first one fails.</p>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/RetryingWrapper/NLog.config" />
+ /// <p>
+ /// The above examples assume just one target and a single rule. See below for
+ /// a programmatic configuration that's equivalent to the above config file:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/RetryingWrapper/Simple/Example.cs" />
+ /// </example>
+ [Target("RetryingWrapper", IgnoresLayout = true, IsWrapper = true)]
+ public class RetryingTargetWrapper: WrapperTargetBase
+ {
+ private int _retryCount = 3;
+ private int _retryDelayMilliseconds = 100;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="RetryingTargetWrapper"/>.
+ /// </summary>
+ public RetryingTargetWrapper()
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="RetryingTargetWrapper"/> and
+ /// initializes the <see cref="WrapperTargetBase.WrappedTarget"/>
+ /// <see cref="RetryCount"/> and <see cref="RetryDelayMilliseconds"/>
+ /// properties.
+ /// </summary>
+ public RetryingTargetWrapper(Target writeTo, int retryCount, int retryDelayMilliseconds)
+ {
+ WrappedTarget = writeTo;
+ RetryCount = retryCount;
+ RetryDelayMilliseconds = retryDelayMilliseconds;
+ }
+
+ /// <summary>
+ /// Number of retries that should be attempted on the wrapped target in case of a failure.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(3)]
+ public int RetryCount
+ {
+ get { return _retryCount; }
+ set { _retryCount = value; }
+ }
+
+ /// <summary>
+ /// The time to wait between retries in milliseconds.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(100)]
+ public int RetryDelayMilliseconds
+ {
+ get { return _retryDelayMilliseconds; }
+ set { _retryDelayMilliseconds = value; }
+ }
+
+ /// <summary>
+ /// Writes the specified log event to the wrapped target, retrying and pausing in case of an error.
+ /// </summary>
+ /// <param name="logEvent">The log event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ for (int i = 0; i < RetryCount; ++i)
+ {
+ try
+ {
+ if (i > 0)
+ InternalLogger.Warn("Retry #{0}", i);
+ WrappedTarget.Write(logEvent);
+ // success, return
+ return;
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Warn("Error while writing to '{0}': {1}", WrappedTarget, ex);
+ if (i == RetryCount - 1)
+ throw ex;
+ System.Threading.Thread.Sleep(RetryDelayMilliseconds);
+ }
+ }
+ }
+ }
+}
diff --git a/src/NLog/Targets/Wrappers/WrapperTargetBase.cs b/src/NLog/Targets/Wrappers/WrapperTargetBase.cs
new file mode 100644
index 0000000..2f0d850
--- /dev/null
+++ b/src/NLog/Targets/Wrappers/WrapperTargetBase.cs
@@ -0,0 +1,110 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Threading;
+using System.Collections;
+using System.Collections.Specialized;
+
+using NLog;
+using NLog.Config;
+
+using NLog.Internal;
+
+namespace NLog.Targets.Wrappers
+{
+ /// <summary>
+ /// Base class for targets wrap other (single) targets.
+ /// </summary>
+ public abstract class WrapperTargetBase: Target
+ {
+ private Target _wrappedTarget = null;
+
+ /// <summary>
+ /// The target that this target wraps.
+ /// </summary>
+ public Target WrappedTarget
+ {
+ get { return _wrappedTarget; }
+ set { _wrappedTarget = value; }
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ base.PopulateLayouts (layouts);
+ WrappedTarget.PopulateLayouts(layouts);
+ }
+
+ /// <summary>
+ /// Closes the target by forwarding the call to the <see cref="WrapperTargetBase.WrappedTarget"/> object.
+ /// </summary>
+ protected internal override void Close()
+ {
+ base.Close();
+ WrappedTarget.Close();
+ }
+
+ /// <summary>
+ /// Forwards the call to <see cref="WrapperTargetBase.WrappedTarget"/>.NeedsStackTrace().
+ /// </summary>
+ /// <returns>The value of forwarded call</returns>
+ protected internal override int NeedsStackTrace()
+ {
+ return WrappedTarget.NeedsStackTrace();
+ }
+
+ /// <summary>
+ /// Initializes the target by forwarding the call
+ /// to <see cref="Target.Initialize"/> to the <see cref="WrapperTargetBase.WrappedTarget"/>.
+ /// </summary>
+ public override void Initialize()
+ {
+ WrappedTarget.Initialize();
+ }
+
+ /// <summary>
+ /// Returns the text representation of the object. Used for diagnostics.
+ /// </summary>
+ /// <returns>A string that describes the target.</returns>
+ public override string ToString()
+ {
+ return ((this.Name != null) ? this.Name : "unnamed") + ":" + this.GetType().Name + "(" + ((WrappedTarget != null) ? WrappedTarget.ToString() : "null") + ")";
+ }
+ }
+}
diff --git a/src/NLog/Web/NLogHttpModule.cs b/src/NLog/Web/NLogHttpModule.cs
new file mode 100644
index 0000000..fbe5a1c
--- /dev/null
+++ b/src/NLog/Web/NLogHttpModule.cs
@@ -0,0 +1,95 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.Web;
+
+using NLog;
+using NLog.Config;
+
+namespace NLog.Web
+{
+ /// <summary>
+ /// ASP.NET HttpModule that enables NLog to hook BeginRequest and EndRequest events easily.
+ /// </summary>
+ public class NLogHttpModule : IHttpModule
+ {
+ /// <summary>
+ /// Event to be raised at the end of each HTTP Request.
+ /// </summary>
+ public static event EventHandler EndRequest;
+
+ /// <summary>
+ /// Event to be raised at the beginning of each HTTP Request.
+ /// </summary>
+ public static event EventHandler BeginRequest;
+
+ /// <summary>
+ /// Initializes the HttpModule
+ /// </summary>
+ /// <param name="application">ASP.NET application</param>
+ public void Init(HttpApplication application)
+ {
+ application.BeginRequest += new EventHandler(this.BeginRequestHandler);
+ application.EndRequest += new EventHandler(this.EndRequestHandler);
+ }
+
+ /// <summary>
+ /// Disposes the module.
+ /// </summary>
+ public void Dispose()
+ {
+ }
+
+ private void BeginRequestHandler(object sender, EventArgs args)
+ {
+ if (BeginRequest != null)
+ {
+ BeginRequest(sender, args);
+ }
+ }
+
+ private void EndRequestHandler(object sender, EventArgs args)
+ {
+ if (EndRequest != null)
+ {
+ EndRequest(sender, args);
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Win32/ASPHelper.cs b/src/NLog/Win32/ASPHelper.cs
new file mode 100644
index 0000000..93a5ed9
--- /dev/null
+++ b/src/NLog/Win32/ASPHelper.cs
@@ -0,0 +1,244 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+namespace NLog.Win32
+{
+ internal class ASPHelper
+ {
+ private ASPHelper() { }
+
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("51372ae0-cae7-11cf-be81-00aa00a2fa25")]
+ public interface IObjectContext
+ {
+ // members not important
+ }
+
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("51372af4-cae7-11cf-be81-00aa00a2fa25")]
+ public interface IGetContextProperties
+ {
+ int Count();
+ object GetProperty(string name);
+ // EnumNames omitted
+ }
+
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("D97A6DA0-A865-11cf-83AF-00A0C90C2BD8")]
+ public interface ISessionObject
+ {
+ string GetSessionID();
+ object GetValue(string name);
+ void PutValue(string name, object val);
+ int GetTimeout();
+ void PutTimeout(int t);
+ void Abandon();
+ int GetCodePage();
+ void PutCodePage(int cp);
+ int GetLCID();
+ void PutLCID();
+ // GetStaticObjects
+ // GetContents
+ }
+
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("D97A6DA0-A866-11cf-83AE-10A0C90C2BD8")]
+ public interface IApplicationObject
+ {
+ object GetValue(string name);
+ void PutValue(string name, object val);
+ // remaining methods removed
+ }
+
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("D97A6DA0-A85D-11cf-83AE-00A0C90C2BD8")]
+ public interface IStringList
+ {
+ object GetItem(object key);
+ int GetCount();
+ object NewEnum();
+ }
+
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("D97A6DA0-A85F-11df-83AE-00A0C90C2BD8")]
+ public interface IRequestDictionary
+ {
+ object GetItem(object var);
+ object NewEnum();
+ int GetCount();
+ object Key(object varKey);
+ }
+
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-C000-000000000046")]
+ public interface IDispatch{}
+
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("D97A6DA0-A861-11cf-93AE-00A0C90C2BD8")]
+ public interface IRequest
+ {
+ IDispatch GetItem(string name);
+ IRequestDictionary GetQueryString();
+ IRequestDictionary GetForm();
+ IRequestDictionary GetBody();
+ IRequestDictionary GetServerVariables();
+ IRequestDictionary GetClientCertificates();
+ IRequestDictionary GetCookies();
+ int GetTotalBytes();
+ void BinaryRead(); // ignored
+ }
+
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("D97A6DA0-A864-11cf-83BE-00A0C90C2BD8")]
+ public interface IResponse
+ {
+ void GetBuffer(); // placeholder
+ void PutBuffer(); // placeholder
+ void GetContentType(); // placeholder
+ void PutContentType(); // placeholder
+ void GetExpires(); // placeholder
+ void PutExpires(); // placeholder
+ void GetExpiresAbsolute(); // placeholder
+ void PutExpiresAbsolute(); // placeholder
+ void GetCookies();
+ void GetStatus();
+ void PutStatus();
+ void Add();
+ void AddHeader();
+ void AppendToLog(); // anybody uses this?
+ void BinaryWrite();
+ void Clear();
+ void End();
+ void Flush();
+ void Redirect();
+ void Write(object text);
+
+ // other members omitted
+ }
+
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("71EAF260-0CE0-11D0-A53E-00A0C90C2091")]
+ public interface IReadCookie
+ {
+ void GetItem(object key, out object val);
+ object HasKeys();
+ void GetNewEnum();
+ void GetCount(out int count);
+ object GetKey(object key);
+ }
+
+ [DllImport("ole32.dll")]
+ extern static int CoGetObjectContext(ref Guid iid, out IObjectContext g);
+
+ static Guid IID_IObjectContext = new Guid("51372ae0-cae7-11cf-be81-00aa00a2fa25");
+
+ public static ISessionObject GetSessionObject()
+ {
+ ISessionObject session = null;
+
+ IObjectContext obj;
+ if (0 == CoGetObjectContext(ref IID_IObjectContext, out obj))
+ {
+ IGetContextProperties prop = (IGetContextProperties)obj;
+ if (prop != null)
+ {
+ session = (ISessionObject)prop.GetProperty("Session");
+ Marshal.ReleaseComObject(prop);
+ }
+ Marshal.ReleaseComObject(obj);
+ }
+ return session;
+ }
+
+ public static IApplicationObject GetApplicationObject()
+ {
+ IApplicationObject app = null;
+
+ IObjectContext obj;
+ if (0 == CoGetObjectContext(ref IID_IObjectContext, out obj))
+ {
+ IGetContextProperties prop = (IGetContextProperties)obj;
+ if (prop != null)
+ {
+ app = (IApplicationObject)prop.GetProperty("Application");
+ Marshal.ReleaseComObject(prop);
+ }
+ Marshal.ReleaseComObject(obj);
+ }
+ return app;
+ }
+
+ public static IRequest GetRequestObject()
+ {
+ IRequest request = null;
+
+ IObjectContext obj;
+ if (0 == CoGetObjectContext(ref IID_IObjectContext, out obj))
+ {
+ IGetContextProperties prop = (IGetContextProperties)obj;
+ if (prop != null)
+ {
+ request = (IRequest)prop.GetProperty("Request");
+ Marshal.ReleaseComObject(prop);
+ }
+ Marshal.ReleaseComObject(obj);
+ }
+ return request;
+ }
+
+ public static IResponse GetResponseObject()
+ {
+ IResponse Response = null;
+
+ IObjectContext obj;
+ if (0 == CoGetObjectContext(ref IID_IObjectContext, out obj))
+ {
+ IGetContextProperties prop = (IGetContextProperties)obj;
+ if (prop != null)
+ {
+ Response = (IResponse)prop.GetProperty("Response");
+ Marshal.ReleaseComObject(prop);
+ }
+ Marshal.ReleaseComObject(obj);
+ }
+
+ return Response;
+ }
+
+ public static object GetComDefaultProperty(object o)
+ {
+ if (o == null)
+ return null;
+ return o.GetType().InvokeMember("", BindingFlags.GetProperty, null, o, new Object[] {});
+ }
+
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/NLog/Win32/LayoutRenderers/ASPApplication.cs b/src/NLog/Win32/LayoutRenderers/ASPApplication.cs
new file mode 100644
index 0000000..eacc6aa
--- /dev/null
+++ b/src/NLog/Win32/LayoutRenderers/ASPApplication.cs
@@ -0,0 +1,104 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+
+using NLog.LayoutRenderers;
+using NLog.Config;
+using System.ComponentModel;
+
+namespace NLog.Win32.LayoutRenderers
+{
+ /// <summary>
+ /// ASP Application variable.
+ /// </summary>
+ [LayoutRenderer("asp-application")]
+ [SupportedRuntime(OS=RuntimeOS.Windows)]
+ [SupportedRuntime(OS=RuntimeOS.WindowsNT)]
+ public class ASPApplicationValueLayoutRenderer: LayoutRenderer
+ {
+ private string _appVariable;
+
+ /// <summary>
+ /// The variable name.
+ /// </summary>
+ [RequiredParameter]
+ [DefaultParameter]
+ public string Variable
+ {
+ get { return _appVariable; }
+ set { _appVariable = value; }
+
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// Because ASP target uses COM Interop which is quite expensive, this method always returns 64.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 64;
+ }
+
+ /// <summary>
+ /// Renders the specified ASP Application variable and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ ASPHelper.IApplicationObject app = ASPHelper.GetApplicationObject();
+ if (app != null)
+ {
+ if (Variable != null)
+ {
+
+ object variableValue = app.GetValue(Variable);
+ builder.Append(Convert.ToString(variableValue));
+ }
+ Marshal.ReleaseComObject(app);
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Win32/LayoutRenderers/ASPRequest.cs b/src/NLog/Win32/LayoutRenderers/ASPRequest.cs
new file mode 100644
index 0000000..9401d0b
--- /dev/null
+++ b/src/NLog/Win32/LayoutRenderers/ASPRequest.cs
@@ -0,0 +1,187 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.Reflection;
+
+using NLog.Config;
+using NLog.LayoutRenderers;
+using System.ComponentModel;
+
+namespace NLog.Win32.LayoutRenderers
+{
+ /// <summary>
+ /// ASP Request variable
+ /// </summary>
+ [LayoutRenderer("asp-request")]
+ [SupportedRuntime(OS=RuntimeOS.Windows)]
+ [SupportedRuntime(OS=RuntimeOS.WindowsNT)]
+ public class ASPRequestValueLayoutRenderer: LayoutRenderer
+ {
+ private string _queryStringKey;
+ private string _formKey;
+ private string _cookie;
+ private string _item;
+ private string _serverVariable;
+
+ /// <summary>
+ /// The item name. The QueryString, Form, Cookies, or ServerVariables collection variables having the specified name are rendered.
+ /// </summary>
+ [DefaultParameter]
+ public string Item
+ {
+ get { return _item; }
+ set { _item = value; }
+ }
+
+
+ /// <summary>
+ /// The QueryString variable to be rendered.
+ /// </summary>
+ public string QueryString
+ {
+ get { return _queryStringKey; }
+ set { _queryStringKey = value; }
+ }
+
+ /// <summary>
+ /// The form variable to be rendered.
+ /// </summary>
+ public string Form
+ {
+ get { return _formKey; }
+ set { _formKey = value; }
+ }
+
+ /// <summary>
+ /// The cookie to be rendered.
+ /// </summary>
+ public string Cookie
+ {
+ get { return _cookie; }
+ set { _cookie = value; }
+ }
+
+ /// <summary>
+ /// The ServerVariables item to be rendered.
+ /// </summary>
+ public string ServerVariable
+ {
+ get { return _serverVariable; }
+ set { _serverVariable = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// Because ASP target uses COM Interop which is quite expensive, this method always returns 64.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 64;
+ }
+
+ private string GetItem(ASPHelper.IRequestDictionary dict, string key)
+ {
+ object retVal = null;
+ object o = dict.GetItem(key);
+ ASPHelper.IStringList sl = o as ASPHelper.IStringList;
+ if (sl != null)
+ {
+ if (sl.GetCount() > 0)
+ {
+ retVal = sl.GetItem(1);
+ }
+ Marshal.ReleaseComObject(sl);
+ }
+ else
+ return o.GetType().ToString();
+ return Convert.ToString(retVal);
+ }
+
+ /// <summary>
+ /// Renders the specified ASP Request variable and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ ASPHelper.IRequest request = ASPHelper.GetRequestObject();
+ if (request != null)
+ {
+ if (QueryString != null)
+ {
+ builder.Append(GetItem(request.GetQueryString(), QueryString));
+ }
+ else if (Form != null)
+ {
+ builder.Append(GetItem(request.GetForm(), Form));
+ }
+ else if (Cookie != null)
+ {
+ object cookie = request.GetCookies().GetItem(Cookie);
+ builder.Append(Convert.ToString(ASPHelper.GetComDefaultProperty(cookie)));
+ }
+ else if (ServerVariable != null)
+ {
+ builder.Append(GetItem(request.GetServerVariables(), ServerVariable));
+ }
+ else if (Item != null)
+ {
+ ASPHelper.IDispatch o = request.GetItem(Item);
+ ASPHelper.IStringList sl = o as ASPHelper.IStringList;
+ if (sl != null)
+ {
+ if (sl.GetCount() > 0)
+ {
+ builder.Append(sl.GetItem(1));
+ }
+ Marshal.ReleaseComObject(sl);
+ }
+ }
+
+ Marshal.ReleaseComObject(request);
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Win32/LayoutRenderers/ASPSession.cs b/src/NLog/Win32/LayoutRenderers/ASPSession.cs
new file mode 100644
index 0000000..401881d
--- /dev/null
+++ b/src/NLog/Win32/LayoutRenderers/ASPSession.cs
@@ -0,0 +1,102 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+
+using NLog.LayoutRenderers;
+using NLog.Config;
+using System.ComponentModel;
+
+namespace NLog.Win32.LayoutRenderers
+{
+ /// <summary>
+ /// ASP Session variable.
+ /// </summary>
+ [LayoutRenderer("asp-session")]
+ [SupportedRuntime(OS=RuntimeOS.Windows)]
+ [SupportedRuntime(OS=RuntimeOS.WindowsNT)]
+ public class ASPSessionValueLayoutRenderer: LayoutRenderer
+ {
+ private string _sessionVariable = null;
+
+ /// <summary>
+ /// Session variable name.
+ /// </summary>
+ [RequiredParameter]
+ [DefaultParameter]
+ public string Variable
+ {
+ get { return _sessionVariable; }
+ set { _sessionVariable = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// Because ASP target uses COM Interop which is quite expensive, this method always returns 64.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 64;
+ }
+
+ /// <summary>
+ /// Renders the specified ASP Session variable and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ ASPHelper.ISessionObject session = ASPHelper.GetSessionObject();
+ if (session != null)
+ {
+ if (Variable != null)
+ {
+ object variableValue = session.GetValue(Variable);
+ builder.Append(Convert.ToString(variableValue));
+ }
+ Marshal.ReleaseComObject(session);
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Win32/LayoutRenderers/Registry.cs b/src/NLog/Win32/LayoutRenderers/Registry.cs
new file mode 100644
index 0000000..2aedcfe
--- /dev/null
+++ b/src/NLog/Win32/LayoutRenderers/Registry.cs
@@ -0,0 +1,162 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF_1_0
+
+using System;
+using System.Text;
+using System.IO;
+
+using Microsoft.Win32;
+
+using NLog.LayoutRenderers;
+using NLog.Config;
+
+namespace NLog.Win32.LayoutRenderers
+{
+ /// <summary>
+ /// A value from the Registry.
+ /// </summary>
+ [LayoutRenderer("registry")]
+ [SupportedRuntime(OS=RuntimeOS.Windows)]
+ [SupportedRuntime(OS=RuntimeOS.WindowsNT)]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public class RegistryLayoutRenderer: LayoutRenderer
+ {
+ private string _value = null;
+ private string _defaultValue = null;
+ private string _key = null;
+ private RegistryKey _rootKey = Registry.LocalMachine;
+ private string _subKey = null;
+
+ /// <summary>
+ /// Registry value.
+ /// </summary>
+ public string Value
+ {
+ get { return _value; }
+ set { _value = value; }
+ }
+
+ /// <summary>
+ /// The value to be output when the specified registry key or value is not found.
+ /// </summary>
+ public string DefaultValue
+ {
+ get { return _defaultValue; }
+ set { _defaultValue = value; }
+ }
+
+ /// <summary>
+ /// Registry key.
+ /// </summary>
+ /// <remarks>
+ /// Must have one of the forms:
+ /// <ul>
+ /// <li>HKLM\Key\Full\Name</li>
+ /// <li>HKEY_LOCAL_MACHINE\Key\Full\Name</li>
+ /// <li>HKCU\Key\Full\Name</li>
+ /// <li>HKEY_CURRENT_USER\Key\Full\Name</li>
+ /// </ul>
+ /// </remarks>
+ [RequiredParameter]
+ public string Key
+ {
+ get { return _key; }
+ set
+ {
+ _key = value;
+ int pos = _key.IndexOfAny(new char[]
+ {
+ '\\', '/'
+ }
+
+ );
+ if (pos >= 0)
+ {
+ string root = _key.Substring(0, pos);
+ switch (root.ToUpper())
+ {
+ case "HKEY_LOCAL_MACHINE":
+ case "HKLM":
+ _rootKey = Registry.LocalMachine;
+ break;
+
+ case "HKEY_CURRENT_USER":
+ case "HKCU":
+ _rootKey = Registry.CurrentUser;
+ break;
+
+ default:
+ throw new ArgumentException("Key name is invalid. Root hive not recognized.");
+ }
+ _subKey = _key.Substring(pos + 1).Replace('/', '\\');
+ }
+ else
+ {
+ throw new ArgumentException("Key name is invalid");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// This function always returns 32.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Reads the specified registry key and value and appends it to
+ /// the passed <see cref="StringBuilder"/>.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event. Ignored.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ using(RegistryKey key = _rootKey.OpenSubKey(_subKey))
+ {
+ builder.Append(key.GetValue(Value, DefaultValue));
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Win32/LayoutRenderers/WindowsIdentity.cs b/src/NLog/Win32/LayoutRenderers/WindowsIdentity.cs
new file mode 100644
index 0000000..eafd2be
--- /dev/null
+++ b/src/NLog/Win32/LayoutRenderers/WindowsIdentity.cs
@@ -0,0 +1,142 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !(NETCF)
+using NLog.Config;
+using System;
+using System.Text;
+using System.Security.Principal;
+
+namespace NLog.Win32.LayoutRenderers
+{
+ /// <summary>
+ /// Thread Windows identity information (username)
+ /// </summary>
+ [LayoutRenderer("windows-identity")]
+ [SupportedRuntime(OS=RuntimeOS.Windows)]
+ [SupportedRuntime(OS=RuntimeOS.WindowsNT)]
+ public class WindowsIdentityLayoutRenderer: LayoutRenderer
+ {
+ private bool _includeDomain = true;
+ private bool _includeUserName = true;
+
+ /// <summary>
+ /// Whether domain name should be included.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool Domain
+ {
+ get { return _includeDomain; }
+ set { _includeDomain = value; }
+ }
+
+ /// <summary>
+ /// Whether username should be included.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool UserName
+ {
+ get { return _includeUserName; }
+ set { _includeUserName = value; }
+ }
+
+ /// <summary>
+ /// Returns the estimated number of characters that are needed to
+ /// hold the rendered value for the specified logging event.
+ /// </summary>
+ /// <param name="logEvent">Logging event information.</param>
+ /// <returns>The number of characters.</returns>
+ /// <remarks>
+ /// If the exact number is not known or
+ /// expensive to calculate this function should return a rough estimate
+ /// that's big enough in most cases, but not too big, in order to conserve memory.
+ /// </remarks>
+ protected internal override int GetEstimatedBufferSize(LogEventInfo logEvent)
+ {
+ return 32;
+ }
+
+ /// <summary>
+ /// Renders the current thread windows identity information and appends it to the specified <see cref="StringBuilder" />.
+ /// </summary>
+ /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
+ /// <param name="logEvent">Logging event.</param>
+ protected internal override void Append(StringBuilder builder, LogEventInfo logEvent)
+ {
+ WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent();
+ if (currentIdentity != null)
+ {
+ string output = "";
+
+ if (UserName)
+ {
+ if (Domain)
+ {
+ // username && domain
+
+ output = currentIdentity.Name;
+ }
+ else
+ {
+ // user name but no domain
+
+ int pos = currentIdentity.Name.LastIndexOf('\\');
+ if (pos >= 0)
+ output = currentIdentity.Name.Substring(pos + 1);
+ else
+ output = currentIdentity.Name;
+ }
+ }
+ else
+ {
+ // no username
+
+ if (!Domain)
+ {
+ // nothing to output
+ return;
+ }
+
+ int pos = currentIdentity.Name.IndexOf('\\');
+ if (pos >= 0)
+ output = currentIdentity.Name.Substring(0, pos);
+ else
+ output = currentIdentity.Name;
+ }
+ builder.Append(ApplyPadding(output));
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Win32/Targets/ASPResponse.cs b/src/NLog/Win32/Targets/ASPResponse.cs
new file mode 100644
index 0000000..eeefddf
--- /dev/null
+++ b/src/NLog/Win32/Targets/ASPResponse.cs
@@ -0,0 +1,86 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Runtime.InteropServices;
+
+using NLog.Config;
+using NLog.Targets;
+
+namespace NLog.Win32.Targets
+{
+ /// <summary>
+ /// Outputs logging messages through the ASP Response object.
+ /// </summary>
+ [Target("ASPResponse")]
+ [SupportedRuntime(OS=RuntimeOS.Windows,Framework=RuntimeFramework.DotNetFramework)]
+ [SupportedRuntime(OS=RuntimeOS.WindowsNT,Framework=RuntimeFramework.DotNetFramework)]
+ public sealed class ASPResponseTarget: TargetWithLayout
+ {
+ private bool _addComments;
+
+ /// <summary>
+ /// Add <!-- --> comments around all written texts.
+ /// </summary>
+ public bool AddComments
+ {
+ get { return _addComments; }
+ set { _addComments = value; }
+ }
+
+ /// <summary>
+ /// Outputs the rendered logging event through the <c>OutputDebugString()</c> Win32 API.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ ASPHelper.IResponse response = ASPHelper.GetResponseObject();
+ if (response != null)
+ {
+ if (AddComments)
+ {
+ response.Write("<!-- " + CompiledLayout.GetFormattedMessage(logEvent) + "-->");
+ }
+ else
+ {
+ response.Write(CompiledLayout.GetFormattedMessage(logEvent));
+ }
+ Marshal.ReleaseComObject(response);
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Win32/Targets/ColoredConsole.cs b/src/NLog/Win32/Targets/ColoredConsole.cs
new file mode 100644
index 0000000..2924d3a
--- /dev/null
+++ b/src/NLog/Win32/Targets/ColoredConsole.cs
@@ -0,0 +1,393 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+using NLog.Config;
+using NLog.Targets;
+using NLog.Win32.Targets;
+
+namespace NLog.Win32.Targets
+{
+ /// <summary>
+ /// Writes logging messages to the console with customizable coloring.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/ColoredConsole/Simple/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/ColoredConsole/Simple/Example.cs" />
+ /// <p>
+ /// The result is a colorful console, where each color represents a single log level.
+ /// </p>
+ /// <img src="examples/targets/Screenshots/ColoredConsole/Simple.gif" />
+ /// <p>
+ /// In addition you can configure your own word highlighting rules so that
+ /// particular words or regular expressions will be marked with
+ /// a distinguished color:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/ColoredConsole/Word Highlighting/NLog.config" />
+ /// <p>Programmatic equivalent of the above configuration:</p>
+ /// <code lang="C#" src="examples/targets/Configuration API/ColoredConsole/Word Highlighting/Example.cs" />
+ /// <p>
+ /// Here's the result:
+ /// </p>
+ /// <img src="examples/targets/Screenshots/ColoredConsole/Word Highlighting.gif" />
+ /// <p>
+ /// Custom row highlighting lets you colorize the output by any <a href="conditions.html">condition</a>.
+ /// This example shows how to mark all entries containing the word "serious" with white color on red background
+ /// and mark all entries coming from a particular logger with yellow on blue.
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/ColoredConsole/Row Highlighting/NLog.config" />
+ /// <p>Programmatic equivalent of the above configuration:</p>
+ /// <code lang="C#" src="examples/targets/Configuration API/ColoredConsole/Row Highlighting/Example.cs" />
+ /// <p>
+ /// Here's the result:
+ /// </p>
+ /// <img src="examples/targets/Screenshots/ColoredConsole/Row Highlighting.gif" />
+ /// </example>
+ [Target("ColoredConsole")]
+ [SupportedRuntime(OS=RuntimeOS.Windows)]
+ [SupportedRuntime(OS=RuntimeOS.WindowsNT)]
+ [NotSupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework)]
+ public sealed class ColoredConsoleTarget: TargetWithLayoutHeaderAndFooter
+ {
+ private bool _errorStream = false;
+ private bool _useDefaultRowHighlightingRules = true;
+ private ConsoleRowHighlightingRuleCollection _ConsoleRowHighlightingRules = new ConsoleRowHighlightingRuleCollection();
+ private ConsoleWordHighlightingRuleCollection _consoleWordHighlightingRules = new ConsoleWordHighlightingRuleCollection();
+ private static ConsoleRowHighlightingRuleCollection _defaultConsoleRowHighlightingRules = new ConsoleRowHighlightingRuleCollection();
+ private ushort[] _colorStack = new ushort[10];
+
+ static ColoredConsoleTarget()
+ {
+ _defaultConsoleRowHighlightingRules.Add(new ConsoleRowHighlightingRule("level == LogLevel.Fatal", ConsoleOutputColor.Red, ConsoleOutputColor.NoChange));
+ _defaultConsoleRowHighlightingRules.Add(new ConsoleRowHighlightingRule("level == LogLevel.Error", ConsoleOutputColor.Yellow, ConsoleOutputColor.NoChange));
+ _defaultConsoleRowHighlightingRules.Add(new ConsoleRowHighlightingRule("level == LogLevel.Warn", ConsoleOutputColor.Magenta, ConsoleOutputColor.NoChange));
+ _defaultConsoleRowHighlightingRules.Add(new ConsoleRowHighlightingRule("level == LogLevel.Info", ConsoleOutputColor.White, ConsoleOutputColor.NoChange));
+ _defaultConsoleRowHighlightingRules.Add(new ConsoleRowHighlightingRule("level == LogLevel.Debug", ConsoleOutputColor.Gray, ConsoleOutputColor.NoChange));
+ _defaultConsoleRowHighlightingRules.Add(new ConsoleRowHighlightingRule("level == LogLevel.Trace", ConsoleOutputColor.DarkGray, ConsoleOutputColor.NoChange));
+ }
+
+ /// <summary>
+ /// Determines whether the error stream (stderr) should be used instead of the output stream (stdout).
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool ErrorStream
+ {
+ get { return _errorStream; }
+ set { _errorStream = value; }
+ }
+
+ /// <summary>
+ /// Use default row highlighting rules.
+ /// </summary>
+ /// <remarks>
+ /// The default rules are:
+ /// <table class="subparamtable">
+ /// <tr>
+ /// <th>Condition</th>
+ /// <th>Foreground Color</th>
+ /// <th>Background Color</th>
+ /// </tr>
+ /// <tr>
+ /// <td>level == LogLevel.Fatal</td>
+ /// <td>Red</td>
+ /// <td>NoChange</td>
+ /// </tr>
+ /// <tr>
+ /// <td>level == LogLevel.Error</td>
+ /// <td>Yellow</td>
+ /// <td>NoChange</td>
+ /// </tr>
+ /// <tr>
+ /// <td>level == LogLevel.Warn</td>
+ /// <td>Magenta</td>
+ /// <td>NoChange</td>
+ /// </tr>
+ /// <tr>
+ /// <td>level == LogLevel.Info</td>
+ /// <td>White</td>
+ /// <td>NoChange</td>
+ /// </tr>
+ /// <tr>
+ /// <td>level == LogLevel.Debug</td>
+ /// <td>Gray</td>
+ /// <td>NoChange</td>
+ /// </tr>
+ /// <tr>
+ /// <td>level == LogLevel.Trace</td>
+ /// <td>DarkGray</td>
+ /// <td>NoChange</td>
+ /// </tr>
+ /// </table>
+ /// </remarks>
+ [System.ComponentModel.DefaultValue(true)]
+ public bool UseDefaultRowHighlightingRules
+ {
+ get { return _useDefaultRowHighlightingRules; }
+ set { _useDefaultRowHighlightingRules = value; }
+ }
+
+ /// <summary>
+ /// Row highlighting rules.
+ /// </summary>
+ [ArrayParameter(typeof(ConsoleRowHighlightingRule), "highlight-row")]
+ public ConsoleRowHighlightingRuleCollection RowHighlightingRules
+ {
+ get { return _ConsoleRowHighlightingRules; }
+ }
+
+ /// <summary>
+ /// Word highlighting rules.
+ /// </summary>
+ [ArrayParameter(typeof(ConsoleWordHighlightingRule), "highlight-word")]
+ public ConsoleWordHighlightingRuleCollection WordHighlightingRules
+ {
+ get { return _consoleWordHighlightingRules; }
+ }
+
+ /// <summary>
+ /// Writes the specified log event to the console highlighting entries
+ /// and words based on a set of defined rules.
+ /// </summary>
+ /// <param name="logEvent">Log event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ Output(logEvent, CompiledLayout.GetFormattedMessage(logEvent));
+ }
+
+ private void Output(LogEventInfo logEvent, string message)
+ {
+ IntPtr hConsole = ConsoleWin32Api.GetStdHandle(ErrorStream ? ConsoleWin32Api.STD_ERROR_HANDLE : ConsoleWin32Api.STD_OUTPUT_HANDLE);
+
+ ConsoleWin32Api.CONSOLE_SCREEN_BUFFER_INFO csbi;
+ ConsoleWin32Api.GetConsoleScreenBufferInfo(hConsole, out csbi);
+
+ ConsoleRowHighlightingRule matchingRule = null;
+
+ foreach (ConsoleRowHighlightingRule cr in RowHighlightingRules)
+ {
+ if (cr.CheckCondition(logEvent))
+ {
+ matchingRule = cr;
+ break;
+ }
+ }
+
+ if (UseDefaultRowHighlightingRules && matchingRule == null)
+ {
+ foreach (ConsoleRowHighlightingRule cr in _defaultConsoleRowHighlightingRules)
+ {
+ if (cr.CheckCondition(logEvent))
+ {
+ matchingRule = cr;
+ break;
+ }
+ }
+ }
+
+ if (matchingRule == null)
+ matchingRule = ConsoleRowHighlightingRule.Default;
+
+ ushort newColor = ColorFromForegroundAndBackground(csbi.wAttributes, matchingRule.ForegroundColor, matchingRule.BackgroundColor);
+
+ message = message.Replace("\a","\a\a");
+
+ foreach (ConsoleWordHighlightingRule hl in WordHighlightingRules)
+ {
+ message = hl.ReplaceWithEscapeSequences(message);
+ }
+
+ if (ErrorStream)
+ ColorizeEscapeSequences(Console.Error, hConsole, message, newColor, csbi.wAttributes);
+ else
+ ColorizeEscapeSequences(Console.Out, hConsole, message, newColor, csbi.wAttributes);
+
+ ConsoleWin32Api.CONSOLE_SCREEN_BUFFER_INFO csbi2;
+ ConsoleWin32Api.GetConsoleScreenBufferInfo(hConsole, out csbi2);
+ ConsoleWin32Api.SetConsoleTextAttribute(hConsole, csbi.wAttributes);
+
+ int xsize = csbi2.dwSize.x;
+ int xpos = csbi2.dwCursorPosition.x;
+ uint written = 0;
+ ConsoleWin32Api.FillConsoleOutputAttribute(hConsole, newColor, xsize - xpos, csbi2.dwCursorPosition, out written);
+ ConsoleWin32Api.SetConsoleTextAttribute(hConsole, csbi.wAttributes);
+ if (ErrorStream)
+ Console.Error.WriteLine();
+ else
+ Console.WriteLine();
+ }
+
+ private void ColorizeEscapeSequences(TextWriter output, IntPtr hConsole, string message, ushort startingAttribute, ushort defaultAttribute)
+ {
+ lock (this)
+ {
+ int colorStackLength = 0;
+ _colorStack[colorStackLength++] = startingAttribute;
+
+ ConsoleWin32Api.SetConsoleTextAttribute(hConsole, startingAttribute);
+
+ int p0 = 0;
+
+ while (p0 < message.Length)
+ {
+ int p1 = p0;
+ while (p1 < message.Length && message[p1] >= 32)
+ {
+ p1++;
+ }
+ // text
+ if (p1 != p0)
+ {
+ output.Write(message.Substring(p0, p1 - p0));
+ }
+ if (p1 >= message.Length)
+ {
+ p0 = p1;
+ break;
+ }
+
+ // control characters
+ char c1 = message[p1];
+ char c2 = (char)0;
+
+ if (p1 + 1 < message.Length)
+ c2 = message[p1 + 1];
+
+ if (c1 == '\a' && c2 == '\a')
+ {
+ output.Write('\a');
+ p0 = p1 + 2;
+ continue;
+ }
+ if (c1 == '\r' || c1 == '\n')
+ {
+ ConsoleWin32Api.SetConsoleTextAttribute(hConsole, defaultAttribute);
+ output.Write(c1);
+ ConsoleWin32Api.SetConsoleTextAttribute(hConsole, _colorStack[colorStackLength - 1]);
+ p0 = p1 + 1;
+ continue;
+ }
+ if (c1 == '\a')
+ {
+ if (c2 == 'X')
+ {
+ colorStackLength--;
+ ConsoleWin32Api.SetConsoleTextAttribute(hConsole, _colorStack[colorStackLength - 1]);
+ p0 = p1 + 2;
+ continue;
+ }
+ else
+ {
+ ConsoleOutputColor foreground = (ConsoleOutputColor)(int)(c2 - 'A');
+ ConsoleOutputColor background = (ConsoleOutputColor)(int)(message[p1 + 2] - 'A');
+ ushort newColor = ColorFromForegroundAndBackground(
+ _colorStack[colorStackLength - 1], foreground, background);
+
+ _colorStack[colorStackLength++] = newColor;
+ ConsoleWin32Api.SetConsoleTextAttribute(hConsole, newColor);
+ p0 = p1 + 3;
+ continue;
+ }
+ }
+
+ output.Write(c1);
+ p0 = p1 + 1;
+ }
+ if (p0 < message.Length)
+ output.Write(message.Substring(p0));
+ }
+ }
+
+ private ushort ColorFromForegroundAndBackground(ushort current, ConsoleOutputColor foregroundColor, ConsoleOutputColor backgroundColor)
+ {
+ ushort newColor = current;
+
+ if (foregroundColor != ConsoleOutputColor.NoChange)
+ {
+ newColor = (ushort)(newColor & ~0xF);
+ newColor |= (ushort )foregroundColor;
+ }
+
+ if (backgroundColor != ConsoleOutputColor.NoChange)
+ {
+ newColor = (ushort)(newColor & ~0xF0);
+ newColor |= (ushort)(((int)backgroundColor) << 4);
+ }
+
+ return newColor;
+ }
+
+ /// <summary>
+ /// Initializes the target.
+ /// </summary>
+ public override void Initialize()
+ {
+ base.Initialize();
+ if (CompiledHeader != null)
+ {
+ LogEventInfo lei = LogEventInfo.CreateNullEvent();
+ Output(lei, CompiledHeader.GetFormattedMessage(lei));
+ }
+ }
+
+ /// <summary>
+ /// Closes the target and releases any unmanaged resources.
+ /// </summary>
+ protected internal override void Close()
+ {
+ if (CompiledFooter != null)
+ {
+ LogEventInfo lei = LogEventInfo.CreateNullEvent();
+ Output(lei, CompiledFooter.GetFormattedMessage(lei));
+ }
+ base.Close();
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Win32/Targets/ConsoleOutputColor.cs b/src/NLog/Win32/Targets/ConsoleOutputColor.cs
new file mode 100644
index 0000000..068a010
--- /dev/null
+++ b/src/NLog/Win32/Targets/ConsoleOutputColor.cs
@@ -0,0 +1,139 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Runtime.InteropServices;
+
+using NLog.Targets;
+
+namespace NLog.Win32.Targets
+{
+ /// <summary>
+ /// Colored console output color.
+ /// </summary>
+ /// <remarks>
+ /// Note that this enumeration is defined to be binary compatible with
+ /// .NET 2.0 System.ConsoleColor + some additions
+ /// </remarks>
+ public enum ConsoleOutputColor
+ {
+ /// <summary>
+ /// Black (#000000)
+ /// </summary>
+ Black = 0,
+
+ /// <summary>
+ /// Dark blue (#000080)
+ /// </summary>
+ DarkBlue = 1,
+
+ /// <summary>
+ /// Dark green (#008000)
+ /// </summary>
+ DarkGreen = 2,
+
+ /// <summary>
+ /// Dark Cyan (#008080)
+ /// </summary>
+ DarkCyan = 3,
+
+ /// <summary>
+ /// Dark Red (#800000)
+ /// </summary>
+ DarkRed = 4,
+
+ /// <summary>
+ /// Dark Magenta (#800080)
+ /// </summary>
+ DarkMagenta = 5,
+
+ /// <summary>
+ /// Dark Yellow (#808000)
+ /// </summary>
+ DarkYellow = 6,
+
+ /// <summary>
+ /// Gray (#C0C0C0)
+ /// </summary>
+ Gray = 7,
+
+ /// <summary>
+ /// Dark Gray (#808080)
+ /// </summary>
+ DarkGray = 8,
+
+ /// <summary>
+ /// Blue (#0000FF)
+ /// </summary>
+ Blue = 9,
+
+ /// <summary>
+ /// Green (#00FF00)
+ /// </summary>
+ Green = 10,
+
+ /// <summary>
+ /// Cyan (#00FFFF)
+ /// </summary>
+ Cyan = 11,
+
+ /// <summary>
+ /// Red (#FF0000)
+ /// </summary>
+ Red = 12,
+
+ /// <summary>
+ /// Magenta (#FF00FF)
+ /// </summary>
+ Magenta = 13,
+
+ /// <summary>
+ /// Yellow (#FFFF00)
+ /// </summary>
+ Yellow = 14,
+
+ /// <summary>
+ /// White (#FFFFFF)
+ /// </summary>
+ White = 15,
+
+ /// <summary>
+ /// Don't change the color.
+ /// </summary>
+ NoChange = 16,
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/NLog/Win32/Targets/ConsoleRowHighlightingRule.cs b/src/NLog/Win32/Targets/ConsoleRowHighlightingRule.cs
new file mode 100644
index 0000000..cfb320d
--- /dev/null
+++ b/src/NLog/Win32/Targets/ConsoleRowHighlightingRule.cs
@@ -0,0 +1,134 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Runtime.InteropServices;
+
+using NLog.Config;
+using NLog.Conditions;
+
+namespace NLog.Win32.Targets
+{
+ /// <summary>
+ /// The row-highlighting condition.
+ /// </summary>
+ public class ConsoleRowHighlightingRule
+ {
+ private ConditionExpression _condition = null;
+ private ConsoleOutputColor _backgroundColor = ConsoleOutputColor.NoChange;
+ private ConsoleOutputColor _foregroundColor = ConsoleOutputColor.NoChange;
+
+ /// <summary>
+ /// Default highlighting rule. Doesn't change the color.
+ /// </summary>
+ public static readonly ConsoleRowHighlightingRule Default = new ConsoleRowHighlightingRule(null, ConsoleOutputColor.NoChange, ConsoleOutputColor.NoChange);
+
+ /// <summary>
+ /// The condition that must be met in order to set the specified foreground and background color.
+ /// </summary>
+ [AcceptsCondition]
+ [RequiredParameter]
+ public string Condition
+ {
+ get
+ {
+ if (_condition == null)
+ return null;
+ else
+ return _condition.ToString();
+ }
+ set
+ {
+ if (value != null)
+ _condition = ConditionParser.ParseExpression(value);
+ else
+ _condition = null;
+ }
+ }
+
+ /// <summary>
+ /// The foreground color.
+ /// </summary>
+ [System.ComponentModel.DefaultValue("NoChange")]
+ public ConsoleOutputColor ForegroundColor
+ {
+ get { return _foregroundColor; }
+ set { _foregroundColor = value; }
+ }
+
+ /// <summary>
+ /// The background color.
+ /// </summary>
+ [System.ComponentModel.DefaultValue("NoChange")]
+ public ConsoleOutputColor BackgroundColor
+ {
+ get { return _backgroundColor; }
+ set { _backgroundColor = value; }
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ConsoleRowHighlightingRule"/>
+ /// </summary>
+ public ConsoleRowHighlightingRule()
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ConsoleRowHighlightingRule"/> and
+ /// assigns Condition, ForegroundColor and BackgroundColor properties.
+ /// </summary>
+ public ConsoleRowHighlightingRule(string condition, ConsoleOutputColor foregroundColor, ConsoleOutputColor backgroundColor)
+ {
+ Condition = condition;
+ ForegroundColor = foregroundColor;
+ BackgroundColor = backgroundColor;
+ }
+
+ /// <summary>
+ /// Checks whether the specified log event matches the condition (if any)
+ /// </summary>
+ /// <param name="logEvent">log event</param>
+ /// <returns><see langword="true"/> if the condition is not defined or
+ /// if it matches, <see langword="false"/> otherwise</returns>
+ public bool CheckCondition(LogEventInfo logEvent)
+ {
+ if (_condition == null)
+ return true;
+ return true.Equals(_condition.Evaluate(logEvent));
+ }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/NLog/Win32/Targets/ConsoleRowHighlightingRuleCollection.cs b/src/NLog/Win32/Targets/ConsoleRowHighlightingRuleCollection.cs
new file mode 100644
index 0000000..4faebdb
--- /dev/null
+++ b/src/NLog/Win32/Targets/ConsoleRowHighlightingRuleCollection.cs
@@ -0,0 +1,244 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Runtime.InteropServices;
+
+using NLog.Targets;
+
+namespace NLog.Win32.Targets
+{
+ /// <summary>
+ /// A collection of elements of type ConsoleRowHighlightingRule
+ /// </summary>
+ public class ConsoleRowHighlightingRuleCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the ConsoleRowHighlightingRuleCollection class.
+ /// </summary>
+ public ConsoleRowHighlightingRuleCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the ConsoleRowHighlightingRuleCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new ConsoleRowHighlightingRuleCollection.
+ /// </param>
+ public ConsoleRowHighlightingRuleCollection(ConsoleRowHighlightingRule[] items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the ConsoleRowHighlightingRuleCollection class, containing elements
+ /// copied from another instance of ConsoleRowHighlightingRuleCollection
+ /// </summary>
+ /// <param name="items">
+ /// The ConsoleRowHighlightingRuleCollection whose elements are to be added to the new ConsoleRowHighlightingRuleCollection.
+ /// </param>
+ public ConsoleRowHighlightingRuleCollection(ConsoleRowHighlightingRuleCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this ConsoleRowHighlightingRuleCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this ConsoleRowHighlightingRuleCollection.
+ /// </param>
+ public virtual void AddRange(ConsoleRowHighlightingRule[] items)
+ {
+ foreach (ConsoleRowHighlightingRule item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another ConsoleRowHighlightingRuleCollection to the end of this ConsoleRowHighlightingRuleCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The ConsoleRowHighlightingRuleCollection whose elements are to be added to the end of this ConsoleRowHighlightingRuleCollection.
+ /// </param>
+ public virtual void AddRange(ConsoleRowHighlightingRuleCollection items)
+ {
+ foreach (ConsoleRowHighlightingRule item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type ConsoleRowHighlightingRule to the end of this ConsoleRowHighlightingRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The ConsoleRowHighlightingRule to be added to the end of this ConsoleRowHighlightingRuleCollection.
+ /// </param>
+ public virtual void Add(ConsoleRowHighlightingRule value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic ConsoleRowHighlightingRule value is in this ConsoleRowHighlightingRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The ConsoleRowHighlightingRule value to locate in this ConsoleRowHighlightingRuleCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this ConsoleRowHighlightingRuleCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(ConsoleRowHighlightingRule value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this ConsoleRowHighlightingRuleCollection
+ /// </summary>
+ /// <param name="value">
+ /// The ConsoleRowHighlightingRule value to locate in the ConsoleRowHighlightingRuleCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(ConsoleRowHighlightingRule value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the ConsoleRowHighlightingRuleCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the ConsoleRowHighlightingRule is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The ConsoleRowHighlightingRule to insert.
+ /// </param>
+ public virtual void Insert(int index, ConsoleRowHighlightingRule value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the ConsoleRowHighlightingRule at the given index in this ConsoleRowHighlightingRuleCollection.
+ /// </summary>
+ public virtual ConsoleRowHighlightingRule this[int index]
+ {
+ get { return (ConsoleRowHighlightingRule) this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific ConsoleRowHighlightingRule from this ConsoleRowHighlightingRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The ConsoleRowHighlightingRule value to remove from this ConsoleRowHighlightingRuleCollection.
+ /// </param>
+ public virtual void Remove(ConsoleRowHighlightingRule value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by ConsoleRowHighlightingRuleCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(ConsoleRowHighlightingRuleCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public ConsoleRowHighlightingRule Current
+ {
+ get { return (ConsoleRowHighlightingRule) (this.wrapped.Current); }
+ }
+
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (ConsoleRowHighlightingRule) (this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this ConsoleRowHighlightingRuleCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual ConsoleRowHighlightingRuleCollection.Enumerator GetEnumerator()
+ {
+ return new ConsoleRowHighlightingRuleCollection.Enumerator(this);
+ }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/NLog/Win32/Targets/ConsoleWin32Api.cs b/src/NLog/Win32/Targets/ConsoleWin32Api.cs
new file mode 100644
index 0000000..36ee2d2
--- /dev/null
+++ b/src/NLog/Win32/Targets/ConsoleWin32Api.cs
@@ -0,0 +1,88 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Runtime.InteropServices;
+
+using NLog.Targets;
+
+namespace NLog.Win32.Targets
+{
+ internal sealed class ConsoleWin32Api
+ {
+ [DllImport("kernel32.dll", SetLastError=true)]
+ internal static extern bool SetConsoleTextAttribute(IntPtr hConsole, ushort wAtributes);
+
+ [DllImport("kernel32.dll", SetLastError=true)]
+ internal static extern bool FillConsoleOutputAttribute(IntPtr hConsole, ushort wAttributes, int nLength, COORD dwWriteCoord, out uint written);
+
+ [DllImport("kernel32.dll", SetLastError=true)]
+ internal static extern bool GetConsoleScreenBufferInfo(IntPtr hConsole, out CONSOLE_SCREEN_BUFFER_INFO bufferInfo);
+
+ internal const int STD_OUTPUT_HANDLE = -11;
+ internal const int STD_ERROR_HANDLE = -12;
+
+ [DllImport("kernel32.dll", SetLastError=true)]
+ internal static extern IntPtr GetStdHandle(int type);
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct COORD
+ {
+ public ushort x;
+ public ushort y;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct SMALL_RECT
+ {
+ public ushort Left;
+ public ushort Top;
+ public ushort Right;
+ public ushort Bottom;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct CONSOLE_SCREEN_BUFFER_INFO
+ {
+ public COORD dwSize;
+ public COORD dwCursorPosition;
+ public ushort wAttributes;
+ public SMALL_RECT srWindow;
+ public COORD dwMaximumWindowSize;
+ }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/NLog/Win32/Targets/ConsoleWordHighlightingRule.cs b/src/NLog/Win32/Targets/ConsoleWordHighlightingRule.cs
new file mode 100644
index 0000000..e715e9c
--- /dev/null
+++ b/src/NLog/Win32/Targets/ConsoleWordHighlightingRule.cs
@@ -0,0 +1,183 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Runtime.InteropServices;
+
+using NLog.Config;
+using NLog.Conditions;
+using NLog.Targets;
+
+namespace NLog.Win32.Targets
+{
+ /// <summary>
+ /// Highlighting rule for Win32 colorful console.
+ /// </summary>
+ public class ConsoleWordHighlightingRule
+ {
+ private string _text;
+ private string _regex;
+ private bool _wholeWords = false;
+ private bool _ignoreCase = false;
+ private Regex _compiledRegex;
+ private ConsoleOutputColor _backgroundColor = ConsoleOutputColor.NoChange;
+ private ConsoleOutputColor _foregroundColor = ConsoleOutputColor.NoChange;
+
+ /// <summary>
+ /// The regular expression to be matched. You must specify either <c>text</c> or <c>regex</c>.
+ /// </summary>
+ public string Regex
+ {
+ get { return _regex; }
+ set { _regex = value; }
+ }
+
+ /// <summary>
+ /// The text to be matched. You must specify either <c>text</c> or <c>regex</c>.
+ /// </summary>
+ public string Text
+ {
+ get { return _text; }
+ set { _text = value; }
+ }
+
+ /// <summary>
+ /// Match whole words only.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool WholeWords
+ {
+ get { return _wholeWords; }
+ set { _wholeWords = value; }
+ }
+
+ /// <summary>
+ /// Ignore case when comparing texts.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool IgnoreCase
+ {
+ get { return _ignoreCase; }
+ set { _ignoreCase = value; }
+ }
+
+ /// <summary>
+ /// Compiled regular expression that matches either Text or Regex property.
+ /// </summary>
+ public Regex CompiledRegex
+ {
+ get
+ {
+ if (_compiledRegex == null)
+ {
+ string regexpression = _regex;
+ if (regexpression == null && _text != null)
+ {
+ regexpression = System.Text.RegularExpressions.Regex.Escape(_text);
+ if (WholeWords)
+ regexpression = "\b" + regexpression + "\b";
+ }
+
+ RegexOptions regexOptions = RegexOptions.Compiled;
+ if (IgnoreCase)
+ regexOptions |= RegexOptions.IgnoreCase;
+
+ _compiledRegex = new Regex(regexpression, regexOptions);
+ }
+
+ return _compiledRegex;
+ }
+ }
+
+ /// <summary>
+ /// The foreground color.
+ /// </summary>
+ [System.ComponentModel.DefaultValue("NoChange")]
+ public ConsoleOutputColor ForegroundColor
+ {
+ get { return _foregroundColor; }
+ set { _foregroundColor = value; }
+ }
+
+ /// <summary>
+ /// The background color.
+ /// </summary>
+ [System.ComponentModel.DefaultValue("NoChange")]
+ public ConsoleOutputColor BackgroundColor
+ {
+ get { return _backgroundColor; }
+ set { _backgroundColor = value; }
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ConsoleWordHighlightingRule"/>
+ /// </summary>
+ public ConsoleWordHighlightingRule()
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ConsoleWordHighlightingRule"/>
+ /// and sets Text, BackgroundColor and ForegroundColor properties.
+ /// </summary>
+ public ConsoleWordHighlightingRule(string text, ConsoleOutputColor foregroundColor, ConsoleOutputColor backgroundColor)
+ {
+ Text = text;
+ ForegroundColor = foregroundColor;
+ BackgroundColor = backgroundColor;
+ }
+
+ internal string MatchEvaluator(Match m)
+ {
+ StringBuilder result = new StringBuilder();
+ result.Append('\a');
+ result.Append((char)((int)this.ForegroundColor + 'A'));
+ result.Append((char)((int)this.BackgroundColor + 'A'));
+ result.Append(m.Value);
+ result.Append('\a');
+ result.Append('X');
+ return result.ToString();
+ }
+
+ internal string ReplaceWithEscapeSequences(string message)
+ {
+ return CompiledRegex.Replace(message, new MatchEvaluator(this.MatchEvaluator));
+ }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/NLog/Win32/Targets/ConsoleWordHighlightingRuleCollection.cs b/src/NLog/Win32/Targets/ConsoleWordHighlightingRuleCollection.cs
new file mode 100644
index 0000000..280ee97
--- /dev/null
+++ b/src/NLog/Win32/Targets/ConsoleWordHighlightingRuleCollection.cs
@@ -0,0 +1,244 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Runtime.InteropServices;
+
+using NLog.Targets;
+
+namespace NLog.Win32.Targets
+{
+ /// <summary>
+ /// A collection of elements of type ConsoleWordHighlightingRule
+ /// </summary>
+ public class ConsoleWordHighlightingRuleCollection: System.Collections.CollectionBase
+ {
+ /// <summary>
+ /// Initializes a new empty instance of the ConsoleWordHighlightingRuleCollection class.
+ /// </summary>
+ public ConsoleWordHighlightingRuleCollection()
+ {
+ // empty
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the ConsoleWordHighlightingRuleCollection class, containing elements
+ /// copied from an array.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the new ConsoleWordHighlightingRuleCollection.
+ /// </param>
+ public ConsoleWordHighlightingRuleCollection(ConsoleWordHighlightingRule[] items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the ConsoleWordHighlightingRuleCollection class, containing elements
+ /// copied from another instance of ConsoleWordHighlightingRuleCollection
+ /// </summary>
+ /// <param name="items">
+ /// The ConsoleWordHighlightingRuleCollection whose elements are to be added to the new ConsoleWordHighlightingRuleCollection.
+ /// </param>
+ public ConsoleWordHighlightingRuleCollection(ConsoleWordHighlightingRuleCollection items)
+ {
+ this.AddRange(items);
+ }
+
+ /// <summary>
+ /// Adds the elements of an array to the end of this ConsoleWordHighlightingRuleCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The array whose elements are to be added to the end of this ConsoleWordHighlightingRuleCollection.
+ /// </param>
+ public virtual void AddRange(ConsoleWordHighlightingRule[] items)
+ {
+ foreach (ConsoleWordHighlightingRule item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds the elements of another ConsoleWordHighlightingRuleCollection to the end of this ConsoleWordHighlightingRuleCollection.
+ /// </summary>
+ /// <param name="items">
+ /// The ConsoleWordHighlightingRuleCollection whose elements are to be added to the end of this ConsoleWordHighlightingRuleCollection.
+ /// </param>
+ public virtual void AddRange(ConsoleWordHighlightingRuleCollection items)
+ {
+ foreach (ConsoleWordHighlightingRule item in items)
+ {
+ this.List.Add(item);
+ }
+ }
+
+ /// <summary>
+ /// Adds an instance of type ConsoleWordHighlightingRule to the end of this ConsoleWordHighlightingRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The ConsoleWordHighlightingRule to be added to the end of this ConsoleWordHighlightingRuleCollection.
+ /// </param>
+ public virtual void Add(ConsoleWordHighlightingRule value)
+ {
+ this.List.Add(value);
+ }
+
+ /// <summary>
+ /// Determines whether a specfic ConsoleWordHighlightingRule value is in this ConsoleWordHighlightingRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The ConsoleWordHighlightingRule value to locate in this ConsoleWordHighlightingRuleCollection.
+ /// </param>
+ /// <returns>
+ /// true if value is found in this ConsoleWordHighlightingRuleCollection;
+ /// false otherwise.
+ /// </returns>
+ public virtual bool Contains(ConsoleWordHighlightingRule value)
+ {
+ return this.List.Contains(value);
+ }
+
+ /// <summary>
+ /// Return the zero-based index of the first occurrence of a specific value
+ /// in this ConsoleWordHighlightingRuleCollection
+ /// </summary>
+ /// <param name="value">
+ /// The ConsoleWordHighlightingRule value to locate in the ConsoleWordHighlightingRuleCollection.
+ /// </param>
+ /// <returns>
+ /// The zero-based index of the first occurrence of the _ELEMENT value if found;
+ /// -1 otherwise.
+ /// </returns>
+ public virtual int IndexOf(ConsoleWordHighlightingRule value)
+ {
+ return this.List.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Inserts an element into the ConsoleWordHighlightingRuleCollection at the specified index
+ /// </summary>
+ /// <param name="index">
+ /// The index at which the ConsoleWordHighlightingRule is to be inserted.
+ /// </param>
+ /// <param name="value">
+ /// The ConsoleWordHighlightingRule to insert.
+ /// </param>
+ public virtual void Insert(int index, ConsoleWordHighlightingRule value)
+ {
+ this.List.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Gets or sets the ConsoleWordHighlightingRule at the given index in this ConsoleWordHighlightingRuleCollection.
+ /// </summary>
+ public virtual ConsoleWordHighlightingRule this[int index]
+ {
+ get { return (ConsoleWordHighlightingRule) this.List[index]; }
+ set { this.List[index] = value; }
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a specific ConsoleWordHighlightingRule from this ConsoleWordHighlightingRuleCollection.
+ /// </summary>
+ /// <param name="value">
+ /// The ConsoleWordHighlightingRule value to remove from this ConsoleWordHighlightingRuleCollection.
+ /// </param>
+ public virtual void Remove(ConsoleWordHighlightingRule value)
+ {
+ this.List.Remove(value);
+ }
+
+ /// <summary>
+ /// Type-specific enumeration class, used by ConsoleWordHighlightingRuleCollection.GetEnumerator.
+ /// </summary>
+ public class Enumerator: System.Collections.IEnumerator
+ {
+ private System.Collections.IEnumerator wrapped;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="collection"></param>
+ public Enumerator(ConsoleWordHighlightingRuleCollection collection)
+ {
+ this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public ConsoleWordHighlightingRule Current
+ {
+ get { return (ConsoleWordHighlightingRule) (this.wrapped.Current); }
+ }
+
+ object System.Collections.IEnumerator.Current
+ {
+ get { return (ConsoleWordHighlightingRule) (this.wrapped.Current); }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool MoveNext()
+ {
+ return this.wrapped.MoveNext();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Reset()
+ {
+ this.wrapped.Reset();
+ }
+ }
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the elements of this ConsoleWordHighlightingRuleCollection.
+ /// </summary>
+ /// <returns>
+ /// An object that implements System.Collections.IEnumerator.
+ /// </returns>
+ public new virtual ConsoleWordHighlightingRuleCollection.Enumerator GetEnumerator()
+ {
+ return new ConsoleWordHighlightingRuleCollection.Enumerator(this);
+ }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/NLog/Win32/Targets/EventLog.cs b/src/NLog/Win32/Targets/EventLog.cs
new file mode 100644
index 0000000..85ce4bd
--- /dev/null
+++ b/src/NLog/Win32/Targets/EventLog.cs
@@ -0,0 +1,257 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Diagnostics;
+using System.Text;
+using System.Globalization;
+
+using NLog.Internal;
+using NLog.Config;
+
+namespace NLog.Win32.Targets
+{
+ /// <summary>
+ /// Writes log message to the Event Log.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/EventLog/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/EventLog/Simple/Example.cs" />
+ /// </example>
+ [Target("EventLog")]
+ [SupportedRuntime(OS=RuntimeOS.WindowsNT,Framework=RuntimeFramework.DotNetFramework)]
+ public class EventLogTarget : TargetWithLayout
+ {
+ private string _machineName = ".";
+ private string _sourceName;
+ private string _logName = "Application";
+ private bool _needEventLogSourceUpdate;
+ private bool _operational;
+ private Layout _eventID = null;
+ private Layout _category = null;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="EventLogTarget"/> and
+ /// </summary>
+ public EventLogTarget()
+ {
+ _sourceName = AppDomain.CurrentDomain.FriendlyName;
+ }
+
+ /// <summary>
+ /// Machine name on which Event Log service is running.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(".")]
+ public string MachineName
+ {
+ get { return _machineName; }
+ set
+ {
+ _machineName = value;
+ _needEventLogSourceUpdate = true;
+ }
+ }
+
+ /// <summary>
+ /// Layout that renders event ID.
+ /// </summary>
+ [AcceptsLayout]
+ public string EventID
+ {
+ get { return Convert.ToString(_eventID); }
+ set { _eventID = new Layout(value); }
+ }
+
+ /// <summary>
+ /// Layout that renders event Category.
+ /// </summary>
+ [AcceptsLayout]
+ public string Category
+ {
+ get { return Convert.ToString(_category); }
+ set { _category = new Layout(value); }
+ }
+
+ /// <summary>
+ /// The value to be used as the event Source.
+ /// </summary>
+ /// <remarks>
+ /// By default this is the friendly name of the current AppDomain.
+ /// </remarks>
+ public string Source
+ {
+ get { return _sourceName; }
+ set
+ {
+ _sourceName = value;
+ _needEventLogSourceUpdate = true;
+ }
+ }
+
+ /// <summary>
+ /// Name of the Event Log to write to. This can be System, Application or
+ /// any user-defined name.
+ /// </summary>
+ [System.ComponentModel.DefaultValue("Application")]
+ public string Log
+ {
+ get { return _logName; }
+ set { _logName = value; }
+ }
+
+ private void UpdateEventLogSource()
+ {
+ if (!_needEventLogSourceUpdate)
+ return;
+
+ lock (this)
+ {
+ _operational = false;
+
+ // if we throw anywhere, we remain non-operational
+
+ try
+ {
+ if (!_needEventLogSourceUpdate)
+ return;
+
+ if (EventLog.SourceExists(_sourceName, _machineName))
+ {
+ string currentLogName = EventLog.LogNameFromSourceName(_sourceName, _machineName);
+ if (currentLogName != _logName)
+ {
+ // re-create the association between Log and Source
+ EventLog.DeleteEventSource(_sourceName, _machineName);
+#if DOTNET_2_0
+ EventSourceCreationData escd = new EventSourceCreationData(_sourceName, _logName);
+ escd.MachineName = _machineName;
+ EventLog.CreateEventSource(escd);
+#else
+ EventLog.CreateEventSource(_sourceName, _logName, _machineName);
+#endif
+ }
+ else
+ {
+ // ok, Source registered and associated with the correct Log
+ }
+ }
+ else
+ {
+#if DOTNET_2_0
+ EventSourceCreationData escd = new EventSourceCreationData(_sourceName, _logName);
+ escd.MachineName = _machineName;
+ EventLog.CreateEventSource(escd);
+#else
+ // source doesn't exist, register it.
+ EventLog.CreateEventSource(_sourceName, _logName, _machineName);
+#endif
+ }
+ // mark the configuration as operational
+ _operational = true;
+ }
+ catch (Exception ex)
+ {
+ InternalLogger.Error("Error when connecting to EventLog: {0}", ex);
+ }
+ finally
+ {
+ _needEventLogSourceUpdate = false;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Writes the specified logging event to the event log.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ UpdateEventLogSource();
+ if (!_operational)
+ return;
+
+ string message = CompiledLayout.GetFormattedMessage(logEvent);
+ if (message.Length > 16384)
+ {
+ // limitation of EventLog API
+ message = message.Substring(0, 16384);
+ }
+
+ EventLogEntryType entryType;
+
+ if (logEvent.Level >= LogLevel.Error)
+ {
+ entryType = EventLogEntryType.Error;
+ }
+ else if (logEvent.Level >= LogLevel.Warn)
+ {
+ entryType = EventLogEntryType.Warning;
+ }
+ else
+ {
+ entryType = EventLogEntryType.Information;
+ }
+
+ int eventID = 0;
+
+ if (_eventID != null)
+ {
+ eventID = Convert.ToInt32(_eventID.GetFormattedMessage(logEvent), CultureInfo.InvariantCulture);
+ }
+
+ short category = 0;
+
+ if (_category != null)
+ {
+ category = Convert.ToInt16(_category.GetFormattedMessage(logEvent), CultureInfo.InvariantCulture);
+ }
+
+ EventLog.WriteEntry(_sourceName, message, entryType, eventID, category);
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Win32/Targets/MSMQ.cs b/src/NLog/Win32/Targets/MSMQ.cs
new file mode 100644
index 0000000..074ab6b
--- /dev/null
+++ b/src/NLog/Win32/Targets/MSMQ.cs
@@ -0,0 +1,224 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF_1_0
+
+using System;
+using System.Messaging;
+using System.Text;
+
+using NLog.Config;
+using System.ComponentModel;
+
+namespace NLog.Win32.Targets
+{
+ /// <summary>
+ /// Writes log message to the specified message queue handled by MSMQ.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/MSMQ/Simple/NLog.config" />
+ /// <p>
+ /// You can use a single target to write to multiple queues (similar to writing to multiple files with the File target).
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/MSMQ/Multiple/NLog.config" />
+ /// <p>
+ /// The above examples assume just one target and a single rule.
+ /// More configuration options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/MSMQ/Simple/Example.cs" />
+ /// </example>
+ [Target("MSMQ")]
+ [SupportedRuntime(Framework=RuntimeFramework.DotNetFramework)]
+ [SupportedRuntime(Framework=RuntimeFramework.DotNetCompactFramework,MinRuntimeVersion="2.0")]
+ public class MSMQTarget : TargetWithLayout
+ {
+ private Layout _queue;
+ private Layout _label = new Layout("NLog");
+ private bool _createIfNotExists;
+ private Encoding _encoding = System.Text.Encoding.UTF8;
+ private bool _useXmlEncoding;
+ private MessagePriority _messagePriority = MessagePriority.Normal;
+ private bool _recoverableMessages;
+
+ /// <summary>
+ /// Name of the queue to write to.
+ /// </summary>
+ /// <remarks>
+ /// To write to a private queue on a local machine use <c>.\private$\QueueName</c>.
+ /// For other available queue names, consult MSMQ documentation.
+ /// </remarks>
+ [RequiredParameter]
+ [AcceptsLayout]
+ public string Queue
+ {
+ get { return _queue.Text; }
+ set { _queue = new Layout(value); }
+ }
+
+ /// <summary>
+ /// The label to associate with each message.
+ /// </summary>
+ /// <remarks>
+ /// By default no label is associated.
+ /// </remarks>
+ [AcceptsLayout]
+ [DefaultValue("NLog")]
+ public string Label
+ {
+ get { return _label.Text; }
+ set { _label = new Layout(value); }
+ }
+
+ /// <summary>
+ /// Create the queue if it doesn't exists.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool CreateQueueIfNotExists
+ {
+ get { return _createIfNotExists; }
+ set { _createIfNotExists = value; }
+ }
+
+ /// <summary>
+ /// Encoding to be used when writing text to the queue.
+ /// </summary>
+ public string Encoding
+ {
+ get { return _encoding.WebName; }
+ set { _encoding = System.Text.Encoding.GetEncoding(value); }
+ }
+
+ /// <summary>
+ /// Use the XML format when serializing message.
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool UseXmlEncoding
+ {
+ get { return _useXmlEncoding; }
+ set { _useXmlEncoding = value; }
+ }
+
+ /// <summary>
+ /// Use recoverable messages (with guaranteed delivery).
+ /// </summary>
+ [System.ComponentModel.DefaultValue(false)]
+ public bool Recoverable
+ {
+ get { return _recoverableMessages; }
+ set { _recoverableMessages = value; }
+ }
+
+ /// <summary>
+ /// Adds all layouts used by this target to the specified collection.
+ /// </summary>
+ /// <param name="layouts">The collection to add layouts to.</param>
+ public override void PopulateLayouts(LayoutCollection layouts)
+ {
+ base.PopulateLayouts (layouts);
+ _queue.PopulateLayouts(layouts);
+ _label.PopulateLayouts(layouts);
+ }
+
+ /// <summary>
+ /// Writes the specified logging event to a queue specified in the Queue
+ /// parameter.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ if (_queue == null)
+ return;
+
+ string queue = _queue.GetFormattedMessage(logEvent);
+
+ if (!MessageQueue.Exists(queue))
+ {
+ if (CreateQueueIfNotExists)
+ MessageQueue.Create(queue);
+ else
+ return;
+ }
+
+ using (MessageQueue mq = new MessageQueue(queue))
+ {
+ Message msg = PrepareMessage(logEvent);
+ if (msg != null)
+ {
+ mq.Send(msg);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Prepares a message to be sent to the message queue.
+ /// </summary>
+ /// <param name="logEvent">The log event to be used when calculating label and text to be written.</param>
+ /// <returns>The message to be sent</returns>
+ /// <remarks>
+ /// You may override this method in inheriting classes
+ /// to provide services like encryption or message
+ /// authentication.
+ /// </remarks>
+ protected virtual Message PrepareMessage(LogEventInfo logEvent)
+ {
+ Message msg = new Message();
+ if (_label != null)
+ {
+ msg.Label = _label.GetFormattedMessage(logEvent);
+ }
+ msg.Recoverable = _recoverableMessages;
+ msg.Priority = _messagePriority;
+
+ if (_useXmlEncoding)
+ {
+ msg.Body = CompiledLayout.GetFormattedMessage(logEvent);
+ }
+ else
+ {
+ byte[] dataBytes = _encoding.GetBytes(CompiledLayout.GetFormattedMessage(logEvent));
+
+ msg.BodyStream.Write(dataBytes, 0, dataBytes.Length);
+ }
+ return msg;
+ }
+ }
+}
+
+#endif
diff --git a/src/NLog/Win32/Targets/OutputDebugString.cs b/src/NLog/Win32/Targets/OutputDebugString.cs
new file mode 100644
index 0000000..2bb8ad0
--- /dev/null
+++ b/src/NLog/Win32/Targets/OutputDebugString.cs
@@ -0,0 +1,81 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+using NLog.Targets;
+using NLog.Config;
+
+namespace NLog.Win32.Targets
+{
+ /// <summary>
+ /// Outputs logging messages through the <c>OutputDebugString()</c> Win32 API.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/OutputDebugString/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/OutputDebugString/Simple/Example.cs" />
+ /// </example>
+ [Target("OutputDebugString")]
+ [SupportedRuntime(OS=RuntimeOS.Windows)]
+ [SupportedRuntime(OS=RuntimeOS.WindowsNT)]
+ public sealed class OutputDebugStringTarget: TargetWithLayout
+ {
+ /// <summary>
+ /// Outputs the rendered logging event through the <c>OutputDebugString()</c> Win32 API.
+ /// </summary>
+ /// <param name="logEvent">The logging event.</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ OutputDebugString(CompiledLayout.GetFormattedMessage(logEvent));
+ }
+
+ /// <summary>
+ /// Stub for OutputDebugString native method
+ /// </summary>
+ /// <param name="message">the string to output</param>
+ [DllImport("kernel32.dll")]
+ private static extern void OutputDebugString(string message);
+ }
+}
diff --git a/src/NLog/Win32/Targets/PerfCounterTarget.cs b/src/NLog/Win32/Targets/PerfCounterTarget.cs
new file mode 100644
index 0000000..63c4dbd
--- /dev/null
+++ b/src/NLog/Win32/Targets/PerfCounterTarget.cs
@@ -0,0 +1,236 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#if !NETCF
+
+using System;
+using System.Reflection;
+using System.Diagnostics;
+using System.Collections;
+using NLog.Internal;
+using NLog.Config;
+
+namespace NLog.Win32.Targets
+{
+ /// <summary>
+ /// Increments specified performance counter on each write.
+ /// </summary>
+ /// <example>
+ /// <p>
+ /// To set up the target in the <a href="config.html">configuration file</a>,
+ /// use the following syntax:
+ /// </p>
+ /// <code lang="XML" src="examples/targets/Configuration File/PerfCounter/NLog.config" />
+ /// <p>
+ /// This assumes just one target and a single rule. More configuration
+ /// options are described <a href="config.html">here</a>.
+ /// </p>
+ /// <p>
+ /// To set up the log target programmatically use code like this:
+ /// </p>
+ /// <code lang="C#" src="examples/targets/Configuration API/PerfCounter/Simple/Example.cs" />
+ /// </example>
+ /// <remarks>
+ /// TODO:
+ /// 1. Unable to create a category allowing multiple counter instances (.Net 2.0 API only, probably)
+ /// 2. Is there any way of adding new counters without deleting the whole category?
+ /// 3. There should be some mechanism of resetting the counter (e.g every day starts from 0), or auto-switching to
+ /// another counter instance (with dynamic creation of new instance). This could be done with layouts.
+ /// </remarks>
+ [Target("PerfCounter")]
+ [SupportedRuntime(OS=RuntimeOS.WindowsNT,Framework=RuntimeFramework.DotNetFramework)]
+ public class PerfCounterTarget : Target
+ {
+ private bool _autoCreate = false;
+ private string _categoryName;
+ private string _counterName;
+ private string _instanceName = "";
+ private PerformanceCounterType _counterType = PerformanceCounterType.NumberOfItems32;
+ private static ArrayList _perfCounterTargets = new ArrayList();
+ private PerformanceCounter _perfCounter = null;
+ private bool _operational = true;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="PerfCounterTarget"/>.
+ /// </summary>
+ public PerfCounterTarget()
+ {
+ lock(_perfCounterTargets)
+ {
+ if (!_perfCounterTargets.Contains(this)) _perfCounterTargets.Add(this);
+ }
+ }
+
+ /// <summary>
+ /// Increments the configured performance counter.
+ /// </summary>
+ /// <param name="logEvent">log event</param>
+ protected internal override void Write(LogEventInfo logEvent)
+ {
+ if (!_operational) return;
+ if (_perfCounter == null) InitializePerfCounter();
+ if (_perfCounter == null) return; //not operational
+
+ bool ok = false;
+
+ try
+ {
+ _perfCounter.Increment();
+ ok = true;
+ }
+ finally
+ {
+ _operational = ok;
+ }
+ }
+
+ /// <summary>
+ /// Whether performance counter should be automatically created.
+ /// </summary>
+ public bool AutoCreate
+ {
+ get {return _autoCreate; }
+ set {_autoCreate = value; }
+ }
+
+ /// <summary>
+ /// Performance counter category.
+ /// </summary>
+ [RequiredParameter]
+ public string CategoryName
+ {
+ get {return _categoryName; }
+ set {_categoryName = value; }
+ }
+
+ /// <summary>
+ /// Name of the performance counter.
+ /// </summary>
+ [RequiredParameter]
+ public string CounterName
+ {
+ get {return _counterName; }
+ set {_counterName = value; }
+ }
+
+ /// <summary>
+ /// Instance name.
+ /// </summary>
+ public string InstanceName
+ {
+ get {return _instanceName; }
+ set {_instanceName = value; }
+ }
+
+ /// <summary>
+ /// Performance counter type.
+ /// </summary>
+ public PerformanceCounterType CounterType
+ {
+ get { return _counterType; }
+ set { _counterType = value; }
+ }
+
+ private void InitializePerfCounter()
+ {
+ lock(this)
+ {
+ _operational = true;
+ try
+ {
+ if (_perfCounter != null) { _perfCounter.Close(); _perfCounter = null; }
+ if (_categoryName == null || _counterName == null)
+ {
+ throw new Exception("Missing category name or counter name for target: " + Name);
+ }
+
+ if (!PerformanceCounterCategory.Exists(CategoryName) || !PerformanceCounterCategory.CounterExists(CounterName, CategoryName))
+ {
+ ArrayList targets = new ArrayList();
+ bool doCreate = false;
+ foreach(PerfCounterTarget t in _perfCounterTargets)
+ {
+ if (t.CategoryName == CategoryName)
+ {
+ targets.Add(t);
+ if (t.AutoCreate) doCreate = true;
+ }
+ }
+
+ if (doCreate)
+ {
+ if (PerformanceCounterCategory.Exists(CategoryName))
+ {
+ //delete the whole category and rebuild from scratch
+ PerformanceCounterCategory.Delete(CategoryName);
+ }
+
+ CounterCreationDataCollection ccds = new CounterCreationDataCollection();
+ foreach(PerfCounterTarget t in targets)
+ {
+ CounterCreationData ccd = new CounterCreationData();
+ ccd.CounterName = t._counterName;
+ ccd.CounterType = t._counterType;
+ ccds.Add(ccd);
+ }
+#if DOTNET_2_0
+ PerformanceCounterCategory.Create(CategoryName,
+ "Category created by NLog",
+ (InstanceName != null) ? PerformanceCounterCategoryType.MultiInstance : PerformanceCounterCategoryType.SingleInstance,
+ ccds);
+#else
+ PerformanceCounterCategory.Create(CategoryName,"Category created by NLog",ccds);
+#endif
+ }
+ else
+ {
+ throw new Exception(string.Format("Counter does not exist: {0}|{1}", CounterName, CategoryName));
+ }
+ }
+
+ _perfCounter = new PerformanceCounter(CategoryName, CounterName, InstanceName, false);
+ _operational = true;
+ }
+ catch(Exception ex)
+ {
+ _operational = false;
+ _perfCounter = null;
+ if (LogManager.ThrowExceptions) throw ex;
+ }
+ }
+ }
+
+ }
+}
+
+#endif
diff --git a/src/NLogC/AssemblyInfo.cpp b/src/NLogC/AssemblyInfo.cpp
new file mode 100644
index 0000000..ed70eaa
--- /dev/null
+++ b/src/NLogC/AssemblyInfo.cpp
@@ -0,0 +1,45 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using namespace ::System::Runtime::InteropServices;
+using namespace ::System::Runtime::CompilerServices;
+using namespace ::System::Reflection;
+
+[assembly: AssemblyTitle("NLog for Unmanaged C/C++")];
+[assembly: AssemblyDescription("NLog")];
+[assembly: AssemblyConfiguration("")];
+[assembly: AssemblyCompany("NLog")];
+[assembly: AssemblyProduct("NLog - .NET Logging Library")];
+[assembly: AssemblyCopyright("Copyright (c) 2004-2006 by Jaroslaw Kowalski")];
+[assembly: AssemblyCulture("")];
+[assembly: AssemblyVersion("1.0.0.0")];
diff --git a/src/NLogC/NLogC FAQ.txt b/src/NLogC/NLogC FAQ.txt
new file mode 100644
index 0000000..d360626
--- /dev/null
+++ b/src/NLogC/NLogC FAQ.txt
@@ -0,0 +1,23 @@
+Mini FAQ:
+
+1. Which binaries should I use?
+===============================
+
+Make sure to choose the version that matches your compiler and .NET version.
+Make sure to put the NLog.dll in the same directory where NLogC.dll is located.
+
+2. How to compile?
+==================
+
+That's simple: just add #include "NLogC.h" and link with "NLogC.lib"
+
+3. Where should I put the config file?
+======================================
+
+The reliable way is to put the configuration in "NLog.dll.nlog" file in the same
+directory where NLog.dll is located.
+
+Other options depend on your host application. For example, if are writing
+a ASP.NET application that calls back to C++ code you may also use Web.config
+and/org Web.nlog.
+
diff --git a/src/NLogC/NLogC.cpp b/src/NLogC/NLogC.cpp
new file mode 100644
index 0000000..477cd1e
--- /dev/null
+++ b/src/NLogC/NLogC.cpp
@@ -0,0 +1,431 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include "stdafx.h"
+#include <stdio.h>
+#include "NLogC.h"
+#include <string.h>
+#include <stdarg.h>
+
+using namespace System;
+using namespace System::Reflection;
+using namespace System::IO;
+using namespace NLog;
+
+#define NLOG_BUFFER_SIZE 8192
+
+#pragma managed
+
+static void WriteToA(NLogLevel level, const char * loggerName, const char * messageBuffer)
+{
+ Logger *logger = LogManager::GetLogger(loggerName);
+
+ switch (level)
+ {
+ case NLOG_TRACE:
+ if (logger->IsTraceEnabled)
+ logger->Trace(messageBuffer);
+ break;
+ case NLOG_DEBUG:
+ if (logger->IsDebugEnabled)
+ logger->Debug(messageBuffer);
+ break;
+ case NLOG_INFO:
+ if (logger->IsInfoEnabled)
+ logger->Info(messageBuffer);
+ break;
+ case NLOG_WARN:
+ if (logger->IsWarnEnabled)
+ logger->Warn(messageBuffer);
+ break;
+ case NLOG_ERROR:
+ if (logger->IsErrorEnabled)
+ logger->Error(messageBuffer);
+ break;
+ case NLOG_FATAL:
+ if (logger->IsFatalEnabled)
+ logger->Fatal(messageBuffer);
+ break;
+ }
+}
+
+static void WriteToW(NLogLevel level, const wchar_t * loggerName, const wchar_t * messageBuffer)
+{
+ Logger *logger = LogManager::GetLogger(loggerName);
+ switch (level)
+ {
+ case NLOG_TRACE:
+ if (logger->IsTraceEnabled)
+ logger->Trace(messageBuffer);
+ break;
+ case NLOG_DEBUG:
+ if (logger->IsDebugEnabled)
+ logger->Debug(messageBuffer);
+ break;
+ case NLOG_INFO:
+ if (logger->IsInfoEnabled)
+ logger->Info(messageBuffer);
+ break;
+ case NLOG_WARN:
+ if (logger->IsWarnEnabled)
+ logger->Warn(messageBuffer);
+ break;
+ case NLOG_ERROR:
+ if (logger->IsErrorEnabled)
+ logger->Error(messageBuffer);
+ break;
+ case NLOG_FATAL:
+ if (logger->IsFatalEnabled)
+ logger->Fatal(messageBuffer);
+ break;
+ }
+}
+
+static bool IsLogEnabledA(NLogLevel level, const char * loggerName)
+{
+ Logger *logger = LogManager::GetLogger(loggerName);
+ switch (level)
+ {
+ case NLOG_TRACE:
+ return logger->IsTraceEnabled;
+
+ case NLOG_DEBUG:
+ return logger->IsDebugEnabled;
+
+ case NLOG_INFO:
+ return logger->IsInfoEnabled;
+
+ case NLOG_WARN:
+ return logger->IsWarnEnabled;
+
+ case NLOG_ERROR:
+ return logger->IsErrorEnabled;
+
+ case NLOG_FATAL:
+ return logger->IsFatalEnabled;
+
+ default:
+ return false;
+ }
+}
+
+static bool IsLogEnabledW(NLogLevel level, const wchar_t * loggerName)
+{
+ Logger *logger = LogManager::GetLogger(loggerName);
+ switch (level)
+ {
+ case NLOG_TRACE:
+ return logger->IsTraceEnabled;
+
+ case NLOG_DEBUG:
+ return logger->IsDebugEnabled;
+
+ case NLOG_INFO:
+ return logger->IsInfoEnabled;
+
+ case NLOG_WARN:
+ return logger->IsWarnEnabled;
+
+ case NLOG_ERROR:
+ return logger->IsErrorEnabled;
+
+ case NLOG_FATAL:
+ return logger->IsFatalEnabled;
+
+ default:
+ return false;
+ }
+}
+
+static bool ConfigureFromFileA(const char * fileName)
+{
+ try
+ {
+ LogManager::Configuration = new Config::XmlLoggingConfiguration(fileName);
+ return true;
+ }
+ catch (Exception *)
+ {
+ return false;
+ }
+}
+
+static bool ConfigureFromFileW(const wchar_t * fileName)
+{
+ try
+ {
+ LogManager::Configuration = new Config::XmlLoggingConfiguration(fileName);
+ return true;
+ }
+ catch (System::Exception *)
+ {
+ return false;
+ }
+}
+
+
+
+__gc class MyResolver
+{
+ System::String *_path;
+
+public:
+ MyResolver(String *path)
+ {
+ _path = path;
+ }
+
+ Assembly *ResolveAssembly(Object *sender, ResolveEventArgs *args)
+ {
+ if (args->Name->StartsWith("NLog,"))
+ {
+ return Assembly::LoadFrom(_path);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+};
+
+static void ForceLoadNLogDll()
+{
+ LogManager::CreateNullLogger();
+}
+
+static int Managed_Init2(String *s)
+{
+ try
+ {
+ MyResolver *resolver = new MyResolver(s);
+ ResolveEventHandler *handler = new ResolveEventHandler(resolver, &MyResolver::ResolveAssembly);
+ AppDomain::CurrentDomain->add_AssemblyResolve(handler);
+ ForceLoadNLogDll();
+ AppDomain::CurrentDomain->remove_AssemblyResolve(handler);
+ return 1;
+ }
+ catch (Exception *)
+ {
+ return 0;
+ }
+}
+
+static int Managed_Init(const char *s)
+{
+ return Managed_Init2(s);
+}
+
+static int Managed_Init(const wchar_t *s)
+{
+ return Managed_Init2(s);
+}
+
+int Managed_InitLocal()
+{
+ System::String *myLocation = System::Reflection::Assembly::GetExecutingAssembly()->Location;
+ myLocation = System::IO::Path::Combine(System::IO::Path::GetDirectoryName(myLocation), L"NLog.dll");
+ return Managed_Init2(myLocation);
+}
+
+#pragma unmanaged
+
+NLOGC_API void NLog_TraceA(const char * loggerName, const char * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVA(NLOG_TRACE, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_DebugA(const char * loggerName, const char * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVA(NLOG_DEBUG, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_InfoA(const char * loggerName, const char * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVA(NLOG_INFO, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_WarnA(const char * loggerName, const char * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVA(NLOG_WARN, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_ErrorA(const char * loggerName, const char * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVA(NLOG_ERROR, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_FatalA(const char * loggerName, const char * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVA(NLOG_FATAL, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_LogA(NLogLevel level, const char * loggerName, const char * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVA(level, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_LogVA(NLogLevel level, const char * loggerName, const char * logMessage, va_list args)
+{
+ if (0 != strchr(logMessage, '%'))
+ {
+ if (IsLogEnabledA(level, loggerName))
+ {
+ char messageBuffer[NLOG_BUFFER_SIZE];
+ _vsnprintf(messageBuffer, sizeof(messageBuffer), logMessage, args);
+ WriteToA(level, loggerName, messageBuffer);
+ }
+ }
+ else
+ {
+ WriteToA(level, loggerName, logMessage);
+ }
+}
+
+NLOGC_API void NLog_TraceW(const wchar_t * loggerName, const wchar_t * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVW(NLOG_TRACE, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_DebugW(const wchar_t * loggerName, const wchar_t * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVW(NLOG_DEBUG, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_InfoW(const wchar_t * loggerName, const wchar_t * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVW(NLOG_INFO, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_WarnW(const wchar_t * loggerName, const wchar_t * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVW(NLOG_WARN, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_ErrorW(const wchar_t * loggerName, const wchar_t * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVW(NLOG_ERROR, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_FatalW(const wchar_t * loggerName, const wchar_t * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVW(NLOG_FATAL, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_LogW(NLogLevel level, const wchar_t * loggerName, const wchar_t * logMessage, ...)
+{
+ va_list args;
+ va_start(args, loggerName);
+ NLog_LogVW(level, loggerName, logMessage, args);
+ va_end(args);
+}
+
+NLOGC_API void NLog_LogVW(NLogLevel level, const wchar_t * loggerName, const wchar_t * logMessage, va_list args)
+{
+ wchar_t messageBuffer[NLOG_BUFFER_SIZE];
+ if (0 != wcschr(logMessage, L'%'))
+ {
+ if (IsLogEnabledW(level, loggerName))
+ {
+ _vsnwprintf(messageBuffer, sizeof(messageBuffer), logMessage, args);
+ WriteToW(level, loggerName, messageBuffer);
+ }
+ }
+ else
+ {
+ WriteToW(level, loggerName, logMessage);
+ }
+}
+
+NLOGC_API int NLog_ConfigureFromFileA(const char * fileName)
+{
+ return ConfigureFromFileA(fileName) ? 1 : 0;
+}
+
+NLOGC_API int NLog_ConfigureFromFileW(const wchar_t * fileName)
+{
+ return ConfigureFromFileW(fileName) ? 1 : 0;
+}
+
+NLOGC_API int NLog_InitA(const char *nlogDllPath)
+{
+ return Managed_Init(nlogDllPath);
+}
+
+NLOGC_API int NLog_InitW(const wchar_t *nlogDllPath)
+{
+ return Managed_Init(nlogDllPath);
+}
+
+NLOGC_API int NLog_InitLocal()
+{
+ return Managed_InitLocal();
+}
diff --git a/src/NLogC/NLogC.h b/src/NLogC/NLogC.h
new file mode 100644
index 0000000..055e4c2
--- /dev/null
+++ b/src/NLogC/NLogC.h
@@ -0,0 +1,107 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#ifndef __NLOGC_H
+#define __NLOGC_H
+
+#ifdef NLOGC_EXPORTS
+#define NLOGC_API __declspec(dllexport)
+#else
+#define NLOGC_API __declspec(dllimport)
+#endif
+
+enum NLogLevel
+{
+ NLOG_TRACE,
+ NLOG_DEBUG,
+ NLOG_INFO,
+ NLOG_WARN,
+ NLOG_ERROR,
+ NLOG_FATAL
+};
+
+extern "C" {
+
+NLOGC_API int NLog_InitA(const char *nlogDllFileName);
+NLOGC_API int NLog_ConfigureFromFileA(const char *fileName);
+NLOGC_API void NLog_LogA(NLogLevel level, const char *loggerName, const char *logMessage, ...);
+NLOGC_API void NLog_TraceA(const char *loggerName, const char *logMessage, ...);
+NLOGC_API void NLog_DebugA(const char *loggerName, const char *logMessage, ...);
+NLOGC_API void NLog_InfoA(const char *loggerName, const char *logMessage, ...);
+NLOGC_API void NLog_WarnA(const char *loggerName, const char *logMessage, ...);
+NLOGC_API void NLog_ErrorA(const char *loggerName, const char *logMessage, ...);
+NLOGC_API void NLog_FatalA(const char *loggerName, const char *logMessage, ...);
+NLOGC_API void NLog_LogVA(NLogLevel level, const char *loggerName, const char *logMessage, va_list args);
+
+NLOGC_API int NLog_InitW(const wchar_t *nlogDllFileName);
+NLOGC_API int NLog_ConfigureFromFileW(const wchar_t *fileName);
+NLOGC_API void NLog_LogW(NLogLevel level, const wchar_t *loggerName, const wchar_t *logMessage, ...);
+NLOGC_API void NLog_TraceW(const wchar_t *loggerName, const wchar_t *logMessage, ...);
+NLOGC_API void NLog_DebugW(const wchar_t *loggerName, const wchar_t *logMessage, ...);
+NLOGC_API void NLog_InfoW(const wchar_t *loggerName, const wchar_t *logMessage, ...);
+NLOGC_API void NLog_WarnW(const wchar_t *loggerName, const wchar_t *logMessage, ...);
+NLOGC_API void NLog_ErrorW(const wchar_t *loggerName, const wchar_t *logMessage, ...);
+NLOGC_API void NLog_FatalW(const wchar_t *loggerName, const wchar_t *logMessage, ...);
+NLOGC_API void NLog_LogVW(NLogLevel level, const wchar_t *loggerName, const wchar_t *logMessage, va_list args);
+
+NLOGC_API int NLog_InitLocal();
+
+}
+
+#ifdef UNICODE
+
+#define NLog_Init NLog_InitW
+#define NLog_Log NLog_LogW
+#define NLog_Trace NLog_TraceW
+#define NLog_Debug NLog_DebugW
+#define NLog_Info NLog_InfoW
+#define NLog_Warn NLog_WarnW
+#define NLog_Error NLog_ErrorW
+#define NLog_Fatal NLog_FatalW
+#define NLog_ConfigureFromFile NLog_ConfigureFromFileW
+
+#else
+
+#define NLog_Init NLog_InitA
+#define NLog_Log NLog_LogA
+#define NLog_Trace NLog_TraceA
+#define NLog_Debug NLog_DebugA
+#define NLog_Info NLog_InfoA
+#define NLog_Warn NLog_WarnA
+#define NLog_Error NLog_ErrorA
+#define NLog_Fatal NLog_FatalA
+#define NLog_ConfigureFromFile NLog_ConfigureFromFileA
+
+#endif
+
+#endif // __NLOGC_H
diff --git a/src/NLogC/NLogC.vs2003.vcproj b/src/NLogC/NLogC.vs2003.vcproj
new file mode 100644
index 0000000..bbf45b2
--- /dev/null
+++ b/src/NLogC/NLogC.vs2003.vcproj
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="NLogC.vs2003"
+ ProjectGUID="{63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="2"
+ CharacterSet="2"
+ ManagedExtensions="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;NLOGC_EXPORTS"
+ MinimalRebuild="FALSE"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/NOENTRY /NODEFAULTLIB:nochkclr.obj /INCLUDE:__DllMainCRTStartup at 12"
+ OutputFile="$(OutDir)/NLogC.dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ AssemblyDebug="1"
+ ProgramDatabaseFile="$(OutDir)/NLogC.pdb"
+ SubSystem="2"
+ ImportLibrary="$(OutDir)/NLogC.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="2"
+ CharacterSet="2"
+ ManagedExtensions="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;NLOGC_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/NOENTRY /NODEFAULTLIB:nochkclr.obj /INCLUDE:__DllMainCRTStartup at 12"
+ OutputFile="$(OutDir)/NLogC.dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary="$(OutDir)/NLogC.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ <AssemblyReference
+ RelativePath="{ReferencesPath}\mscorlib.dll"/>
+ <ProjectReference
+ ReferencedProjectIdentifier="{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+ Name="NLog"/>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\AssemblyInfo.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\NLogC.cpp">
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\NLogC.h">
+ </File>
+ <File
+ RelativePath=".\NLogger.h">
+ </File>
+ <File
+ RelativePath=".\stdafx.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/NLogC/NLogC.vs2005.vcproj b/src/NLogC/NLogC.vs2005.vcproj
new file mode 100644
index 0000000..25a0b07
--- /dev/null
+++ b/src/NLogC/NLogC.vs2005.vcproj
@@ -0,0 +1,272 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="NLogC.vs2005"
+ ProjectGUID="{63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}"
+ RootNamespace="NLogC"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ ManagedExtensions="4"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;NLOGC_EXPORTS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/NOENTRY /NODEFAULTLIB:nochkclr.obj /INCLUDE:__DllMainCRTStartup at 12"
+ OutputFile="$(OutDir)/NLogC.dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ AssemblyDebug="1"
+ ProgramDatabaseFile="$(OutDir)/NLogC.pdb"
+ SubSystem="2"
+ ImportLibrary="$(OutDir)/NLogC.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ ManagedExtensions="4"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;NLOGC_EXPORTS"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/NOENTRY /NODEFAULTLIB:nochkclr.obj /INCLUDE:__DllMainCRTStartup at 12"
+ OutputFile="$(OutDir)/NLogC.dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary="$(OutDir)/NLogC.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ <AssemblyReference
+ RelativePath="mscorlib.dll"
+ AssemblyName="mscorlib, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=IA64"
+ />
+ <ProjectReference
+ ReferencedProjectIdentifier="{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+ RelativePathToProject=".\src\NLog\NLog.vs2005.csproj"
+ />
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\AssemblyInfo.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\NLogC.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\NLogC.h"
+ >
+ </File>
+ <File
+ RelativePath=".\NLogger.h"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/NLogC/NLogger.h b/src/NLogC/NLogger.h
new file mode 100644
index 0000000..eb69141
--- /dev/null
+++ b/src/NLogC/NLogger.h
@@ -0,0 +1,93 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#ifndef __NLOGGER_H
+#define __NLOGGER_H
+
+#include <stdarg.h>
+
+#include "NLogC.h"
+
+class NLogger
+{
+ const char *_loggerName;
+
+public:
+ NLogger(const char *loggerName)
+ {
+ _loggerName = loggerName;
+ }
+
+ void Debug(const char *logMessage, ...)
+ {
+ va_list args;
+
+ va_start(args, logMessage);
+ NLog_LogVA(NLOG_DEBUG, _loggerName, logMessage, args);
+ va_end(args);
+ }
+ void Info(const char *logMessage, ...)
+ {
+ va_list args;
+
+ va_start(args, logMessage);
+ NLog_LogVA(NLOG_INFO, _loggerName, logMessage, args);
+ va_end(args);
+ }
+ void Warn(const char *logMessage, ...)
+ {
+ va_list args;
+
+ va_start(args, logMessage);
+ NLog_LogVA(NLOG_WARN, _loggerName, logMessage, args);
+ va_end(args);
+ }
+ void Error(const char *logMessage, ...)
+ {
+ va_list args;
+
+ va_start(args, logMessage);
+ NLog_LogVA(NLOG_ERROR, _loggerName, logMessage, args);
+ va_end(args);
+ }
+ void Fatal(const char *logMessage, ...)
+ {
+ va_list args;
+
+ va_start(args, logMessage);
+ NLog_LogVA(NLOG_FATAL, _loggerName, logMessage, args);
+ va_end(args);
+ }
+};
+
+#endif // __NLOGC_H
diff --git a/src/NLogC/ReadMe.txt b/src/NLogC/ReadMe.txt
new file mode 100644
index 0000000..9b1435d
--- /dev/null
+++ b/src/NLogC/ReadMe.txt
@@ -0,0 +1,32 @@
+========================================================================
+ DYNAMIC LINK LIBRARY : NLogC Project Overview
+========================================================================
+
+AppWizard has created this NLogC DLL for you.
+This file contains a summary of what you will find in each of the files that
+make up your NLogC application.
+
+
+NLogC.vcproj
+ This is the main project file for VC++ projects generated using an Application Wizard.
+ It contains information about the version of Visual C++ that generated the file, and
+ information about the platforms, configurations, and project features selected with the
+ Application Wizard.
+
+NLogC.cpp
+ This is the main DLL source file.
+
+/////////////////////////////////////////////////////////////////////////////
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+ These files are used to build a precompiled header (PCH) file
+ named NLogC.pch and a precompiled types file named StdAfx.obj.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" comments to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/src/NLogC/stdafx.cpp b/src/NLogC/stdafx.cpp
new file mode 100644
index 0000000..2647522
--- /dev/null
+++ b/src/NLogC/stdafx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// NLogC.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/src/NLogC/stdafx.h b/src/NLogC/stdafx.h
new file mode 100644
index 0000000..dec292c
--- /dev/null
+++ b/src/NLogC/stdafx.h
@@ -0,0 +1,13 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+// Windows Header Files:
+//#include <windows.h>
+
+// TODO: reference additional headers your program requires here
diff --git a/src/publisher_policy.config.template b/src/publisher_policy.config.template
new file mode 100644
index 0000000..b4008a3
--- /dev/null
+++ b/src/publisher_policy.config.template
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<configuration>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="" />
+ <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration>
diff --git a/tests/NLog.AsyncBenchmark/App.config b/tests/NLog.AsyncBenchmark/App.config
new file mode 100644
index 0000000..70c85d1
--- /dev/null
+++ b/tests/NLog.AsyncBenchmark/App.config
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<configuration>
+ <configSections>
+ <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
+ </configSections>
+
+ <nlog autoReload="true"
+ internalLogToConsole="false"
+ xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="file_nokeepopen"
+ xsi:type="File"
+ fileName="${basedir}/file.log"
+ layout="${longdate} pid:${processid} tid:${threadid} msg:${message}"
+ networkWrites="true"
+ concurrentWriteAttempts="100"
+ />
+ <target name="file_multiprocess"
+ xsi:type="File"
+ fileName="${basedir}/file.log"
+ layout="${longdate} pid:${processid} tid:${threadid} msg:${message}"
+ concurrentWrites="true"
+ keepFileOpen="true"
+ />
+ <target name="file_singleprocess"
+ xsi:type="File"
+ fileName="${basedir}/file_keepopen.log"
+ layout="${longdate} pid:${processid} tid:${threadid} msg:${message}"
+ concurrentWrites="false"
+ keepFileOpen="true"
+ />
+ <target name="file_nokeepopen_bt"
+ xsi:type="File"
+ fileName="${basedir}/file.${threadid}.log"
+ layout="${longdate} pid:${processid} tid:${threadid} msg:${message}"
+ networkWrites="true"
+ concurrentWriteAttempts="100"
+ />
+ <target name="file_multiprocess_bt"
+ xsi:type="File"
+ fileName="${basedir}/file.${threadid}.log"
+ layout="${longdate} pid:${processid} tid:${threadid} msg:${message}"
+ concurrentWrites="true"
+ keepFileOpen="true"
+ />
+ <target name="file_singleprocess_bt"
+ xsi:type="File"
+ fileName="${basedir}/file_keepopen.${threadid}.log"
+ layout="${longdate} pid:${processid} tid:${threadid} msg:${message}"
+ concurrentWrites="false"
+ keepFileOpen="true"
+ />
+ <target name="file_nokeepopen_bt10"
+ xsi:type="File"
+ fileName="${basedir}/file.${threadid}.log"
+ layout="${longdate} pid:${processid} tid:${threadid} msg:${message}"
+ networkWrites="true"
+ openFileCacheSize="10"
+ concurrentWriteAttempts="100"
+ />
+ <target name="file_multiprocess_bt10"
+ xsi:type="File"
+ fileName="${basedir}/file.${threadid}.log"
+ layout="${longdate} pid:${processid} tid:${threadid} msg:${message}"
+ openFileCacheSize="10"
+ concurrentWrites="true"
+ keepFileOpen="true"
+ />
+ <target name="file_singleprocess_bt10"
+ xsi:type="File"
+ fileName="${basedir}/file_keepopen.${threadid}.log"
+ layout="${longdate} pid:${processid} tid:${threadid} msg:${message}"
+ openFileCacheSize="10"
+ concurrentWrites="false"
+ keepFileOpen="true"
+ />
+ </targets>
+
+ <rules>
+ </rules>
+ </nlog>
+</configuration>
+
diff --git a/tests/NLog.AsyncBenchmark/App.ico b/tests/NLog.AsyncBenchmark/App.ico
new file mode 100644
index 0000000..3a5525f
Binary files /dev/null and b/tests/NLog.AsyncBenchmark/App.ico differ
diff --git a/tests/NLog.AsyncBenchmark/AssemblyInfo.cs b/tests/NLog.AsyncBenchmark/AssemblyInfo.cs
new file mode 100644
index 0000000..afcfb1c
--- /dev/null
+++ b/tests/NLog.AsyncBenchmark/AssemblyInfo.cs
@@ -0,0 +1,91 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.0.0")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+// (*) If no key is specified, the assembly is not signed.
+// (*) KeyName refers to a key that has been installed in the Crypto Service
+// Provider (CSP) on your machine. KeyFile refers to a file which contains
+// a key.
+// (*) If the KeyFile and the KeyName values are both specified, the
+// following processing occurs:
+// (1) If the KeyName can be found in the CSP, that key is used.
+// (2) If the KeyName does not exist and the KeyFile does exist, the key
+// in the KeyFile is installed into the CSP and used.
+// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+// When specifying the KeyFile, the location of the KeyFile should be
+// relative to the project output directory which is
+// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
+// located in the project directory, you would specify the AssemblyKeyFile
+// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+// documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]
diff --git a/tests/NLog.AsyncBenchmark/Class1.cs b/tests/NLog.AsyncBenchmark/Class1.cs
new file mode 100644
index 0000000..63e9a12
--- /dev/null
+++ b/tests/NLog.AsyncBenchmark/Class1.cs
@@ -0,0 +1,312 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Threading;
+using System.IO;
+using System.Diagnostics;
+using System.Reflection;
+
+using NLog;
+
+namespace NLog.AsyncBenchmark
+{
+ class Timing
+ {
+ private Logger _logger;
+ private int _repeatCount;
+ private Thread _thread;
+ private StopWatch _timeToWrite = new StopWatch();
+ private static Mutex _syncStartMutex = new Mutex(false, "NLOG-SYNCSTART");
+ private Exception _exception;
+
+ public Timing(Logger logger, int repeatCount)
+ {
+ _logger = logger;
+ _repeatCount = repeatCount;
+ _exception = null;
+
+ _thread = new Thread(new ThreadStart(ThreadProc));
+ }
+
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static int Main(string[] args)
+ {
+ LogManager.ThrowExceptions = true;
+ if (args.Length > 0 && args[0] == "/child")
+ {
+ Console.Error.WriteLine("AAA");
+ int repetitions = Convert.ToInt32(args[1]);
+ int threads = Convert.ToInt32(args[2]);
+ string targetName = args[3];
+
+ Console.Error.WriteLine("Child #{0} running {1} threads, {2} repetitions on {3}", AppDomain.GetCurrentThreadId(), threads, repetitions, targetName);
+ Target t = LogManager.Configuration.FindTargetByName(targetName);
+
+ double minTime, maxTime, avgTime, timeToFlush;
+ bool gotException;
+
+ // warmup
+ Console.Error.WriteLine("Warming up...");
+ TimeTarget(t, 1, 1, out minTime, out maxTime, out avgTime, out timeToFlush, out gotException);
+
+ // wait on mutex and release immediately
+ // the processes are started with mutex held
+ // so they all wait here.
+
+ Console.Error.WriteLine("Ready and waiting...");
+ _syncStartMutex.WaitOne();
+ _syncStartMutex.ReleaseMutex();
+ Console.Error.WriteLine("Go!");
+
+ TimeTarget(t, threads, repetitions, out minTime, out maxTime, out avgTime, out timeToFlush, out gotException);
+ Console.WriteLine("{0} {1} {2} {3} {4}", minTime, maxTime, avgTime, timeToFlush, gotException ? "1" : "0");
+ Console.Error.WriteLine("Child #{0} finished.", AppDomain.GetCurrentThreadId());
+ return 0;
+ }
+
+ Internal.InternalLogger.LogLevel = LogLevel.Warn;
+ Internal.InternalLogger.LogToConsoleError = true;
+
+ foreach (string s in Directory.GetFiles(".", "*.log"))
+ {
+ File.Delete(s);
+ }
+
+ NLog.Config.LoggingConfiguration defaultConfig = LogManager.Configuration;
+
+ TextWriter output = new StreamWriter("results.csv", false, System.Text.Encoding.ASCII);
+ string separator = Thread.CurrentThread.CurrentCulture.TextInfo.ListSeparator;
+ output.Write("targetName");
+ output.Write(separator);
+ output.Write("processCount");
+ output.Write(separator);
+ output.Write("threadCount");
+ output.Write(separator);
+ output.Write("repetitions");
+ output.Write(separator);
+ output.Write("avgTime");
+ output.Write(separator);
+ output.Write("ttf");
+ output.Write(separator);
+ output.Write("gotException");
+ output.WriteLine();
+ output.Flush();
+ foreach (Target t in defaultConfig.GetConfiguredNamedTargets())
+ {
+ TimeTarget(output, t);
+ }
+ output.Close();
+ return 0;
+ }
+
+ static void TimeTarget(TextWriter output, Target target)
+ {
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ string separator = Thread.CurrentThread.CurrentCulture.TextInfo.ListSeparator;
+ for (int processCount = 1; processCount <= 4; processCount *= 2)
+ {
+ for (int repetitions = 1000; repetitions <= 1000; repetitions *= 10)
+ {
+ for (int threadCount = 1; threadCount <= 1; threadCount *= 4)
+ {
+ Console.WriteLine("Timing '{0}' in {1} processes", target.Name, processCount);
+ Process[] processes = new Process[processCount];
+ for (int i = 0; i < processCount; ++i)
+ {
+ Process p = new Process();
+ p.StartInfo.FileName = Assembly.GetEntryAssembly().Location;
+ p.StartInfo.Arguments = String.Format("/child {0} {1} {2}", repetitions, threadCount, target.Name);
+ p.StartInfo.UseShellExecute = false;
+ p.StartInfo.RedirectStandardOutput = true;
+ //Console.WriteLine("{0}", p.StartInfo.FileName);
+ processes[i] = p;
+ }
+
+ _syncStartMutex.WaitOne();
+ for (int i = 0; i < processCount; ++i)
+ {
+ processes[i].Start();
+ }
+ Console.WriteLine("Ready, steady...");
+ System.Threading.Thread.Sleep(10000);
+ Console.WriteLine("Go!!!!!");
+ _syncStartMutex.ReleaseMutex();
+
+ double min = Double.MaxValue;
+ double max = Double.MinValue;
+ double sum = 0.0;
+ double ttf = Double.MinValue;
+ bool gotException = false;
+
+ for (int i = 0; i < processCount; ++i)
+ {
+ processes[i].WaitForExit();
+ string result = processes[i].StandardOutput.ReadToEnd();
+ processes[i].Dispose();
+
+ string[] results = result.Split(' ');
+ min = Math.Min(min, Convert.ToDouble(results[0]));
+ max = Math.Max(max, Convert.ToDouble(results[1]));
+ sum += Convert.ToDouble(results[2]);
+ ttf = Math.Max(ttf, Convert.ToDouble(results[3]));
+ if (Convert.ToInt32(results[4]) != 0)
+ {
+ gotException = true;
+ }
+ }
+
+ double avg = sum / processCount;
+
+ output.Write(target.Name);
+ output.Write(separator);
+ output.Write(processCount);
+ output.Write(separator);
+ output.Write(threadCount);
+ output.Write(separator);
+ output.Write(repetitions);
+ output.Write(separator);
+ output.Write(Math.Round(avg * 1000.0, 3));
+ output.Write(separator);
+ output.Write(Math.Round(ttf * 1000.0, 3));
+ output.Write(separator);
+ output.Write(gotException);
+ output.WriteLine();
+ output.Flush();
+ }
+ }
+ }
+ }
+
+ static void TimeTarget(Target target, int threadCount, int repetitions, out double minTime, out double maxTime, out double avgTime, out double timeToFlush, out bool gotException)
+ {
+ NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
+
+ Timing[] timings = new Timing[threadCount];
+ StopWatch _timeToFlush = new StopWatch();
+ Logger logger = LogManager.GetLogger("A");
+ for (int i = 0; i < threadCount; ++i)
+ {
+ Timing t = new Timing(logger, repetitions);
+ timings[i] = t;
+ }
+ _timeToFlush.Start();
+ for (int i = 0; i < threadCount; ++i)
+ {
+ timings[i].Run();
+ }
+ for (int i = 0; i < threadCount; ++i)
+ {
+ timings[i].Join();
+ }
+
+ double maxThreadTime = timings[0].ThreadTime;
+ double minThreadTime = timings[0].ThreadTime;
+ double sumThreadTime = timings[0].ThreadTime;
+
+ for (int i = 1; i < threadCount; ++i)
+ {
+ maxThreadTime = Math.Max(maxThreadTime, timings[i].ThreadTime);
+ minThreadTime = Math.Min(minThreadTime, timings[i].ThreadTime);
+ sumThreadTime += timings[i].ThreadTime;
+ }
+
+ gotException = false;
+ for (int i = 0; i < threadCount; ++i)
+ {
+ if (timings[i]._exception != null)
+ {
+ gotException = true;
+ }
+ }
+
+ maxThreadTime /= repetitions;
+ minThreadTime /= repetitions;
+ sumThreadTime /= repetitions;
+
+ double avgThreadTime = sumThreadTime / threadCount;
+
+ LogManager.Flush();
+ _timeToFlush.Stop();
+
+ maxTime = maxThreadTime;
+ minTime = minThreadTime;
+ avgTime = avgThreadTime;
+ timeToFlush = _timeToFlush.Seconds;
+ }
+
+ public void ThreadProc()
+ {
+ _timeToWrite.Start();
+ try
+ {
+ for (int i = 0; i < 10; ++i)
+ {
+ _logger.Debug("Warmup {0}", i);
+ }
+
+ for (int i = 0; i < _repeatCount; ++i)
+ {
+ _logger.Debug("Message {0}", i);
+ }
+ }
+ catch (Exception ex)
+ {
+ _exception = ex;
+ }
+ finally
+ {
+ _timeToWrite.Stop();
+ }
+ }
+
+ void Run()
+ {
+ _thread.Start();
+ }
+
+ void Join()
+ {
+ _thread.Join();
+ }
+
+ public double ThreadTime
+ {
+ get { return _timeToWrite.Seconds; }
+ }
+ }
+}
diff --git a/tests/NLog.AsyncBenchmark/NLog.AsyncBenchmark.vs2003.csproj b/tests/NLog.AsyncBenchmark/NLog.AsyncBenchmark.vs2003.csproj
new file mode 100644
index 0000000..7f3d563
--- /dev/null
+++ b/tests/NLog.AsyncBenchmark/NLog.AsyncBenchmark.vs2003.csproj
@@ -0,0 +1,118 @@
+<VisualStudioProject>
+ <CSHARP
+ ProjectType = "Local"
+ ProductVersion = "7.10.3077"
+ SchemaVersion = "2.0"
+ ProjectGuid = "{F666E83B-3806-4F90-A577-809AA8EEED0E}"
+ >
+ <Build>
+ <Settings
+ ApplicationIcon = "App.ico"
+ AssemblyKeyContainerName = ""
+ AssemblyName = "NLog.AsyncBenchmark"
+ AssemblyOriginatorKeyFile = ""
+ DefaultClientScript = "JScript"
+ DefaultHTMLPageLayout = "Grid"
+ DefaultTargetSchema = "IE50"
+ DelaySign = "false"
+ OutputType = "Exe"
+ PreBuildEvent = ""
+ PostBuildEvent = ""
+ RootNamespace = "NLog.AsyncBenchmark"
+ RunPostBuildEvent = "OnBuildSuccess"
+ StartupObject = ""
+ >
+ <Config
+ Name = "Debug"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "DEBUG;TRACE"
+ DocumentationFile = ""
+ DebugSymbols = "true"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = ""
+ Optimize = "false"
+ OutputPath = "bin\Debug\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ <Config
+ Name = "Release"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "TRACE"
+ DocumentationFile = ""
+ DebugSymbols = "false"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = ""
+ Optimize = "true"
+ OutputPath = "bin\Release\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ </Settings>
+ <References>
+ <Reference
+ Name = "System"
+ AssemblyName = "System"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll"
+ />
+ <Reference
+ Name = "System.Data"
+ AssemblyName = "System.Data"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
+ />
+ <Reference
+ Name = "System.XML"
+ AssemblyName = "System.Xml"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
+ />
+ <Reference
+ Name = "NLog.vs2003"
+ Project = "{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+ Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+ />
+ </References>
+ </Build>
+ <Files>
+ <Include>
+ <File
+ RelPath = "App.config"
+ BuildAction = "None"
+ />
+ <File
+ RelPath = "App.ico"
+ BuildAction = "Content"
+ />
+ <File
+ RelPath = "AssemblyInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Class1.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "StopWatch.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ </Include>
+ </Files>
+ </CSHARP>
+</VisualStudioProject>
+
diff --git a/tests/NLog.AsyncBenchmark/NLog.AsyncBenchmark.vs2005.csproj b/tests/NLog.AsyncBenchmark/NLog.AsyncBenchmark.vs2005.csproj
new file mode 100644
index 0000000..6f6e67d
--- /dev/null
+++ b/tests/NLog.AsyncBenchmark/NLog.AsyncBenchmark.vs2005.csproj
@@ -0,0 +1,112 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectType>Local</ProjectType>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F666E83B-3806-4F90-A577-809AA8EEED0E}</ProjectGuid>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ApplicationIcon>App.ico</ApplicationIcon>
+ <AssemblyKeyContainerName>
+ </AssemblyKeyContainerName>
+ <AssemblyName>NLog.AsyncBenchmark</AssemblyName>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <DefaultClientScript>JScript</DefaultClientScript>
+ <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+ <DefaultTargetSchema>IE50</DefaultTargetSchema>
+ <DelaySign>false</DelaySign>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>NLog.AsyncBenchmark</RootNamespace>
+ <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+ <StartupObject>
+ </StartupObject>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <OutputPath>bin\Debug\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DocumentationFile>
+ </DocumentationFile>
+ <DebugSymbols>true</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>
+ </NoWarn>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>4</WarningLevel>
+ <DebugType>full</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <OutputPath>bin\Release\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>TRACE</DefineConstants>
+ <DocumentationFile>
+ </DocumentationFile>
+ <DebugSymbols>false</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>
+ </NoWarn>
+ <Optimize>true</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>4</WarningLevel>
+ <DebugType>none</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System">
+ <Name>System</Name>
+ </Reference>
+ <Reference Include="System.Data">
+ <Name>System.Data</Name>
+ </Reference>
+ <Reference Include="System.Xml">
+ <Name>System.XML</Name>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ <Content Include="App.ico" />
+ <Compile Include="AssemblyInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Class1.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="StopWatch.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\NLog\NLog.vs2005.csproj">
+ <Project>{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}</Project>
+ <Name>NLog.vs2005</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>
+ </PreBuildEvent>
+ <PostBuildEvent>
+ </PostBuildEvent>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/tests/NLog.AsyncBenchmark/StopWatch.cs b/tests/NLog.AsyncBenchmark/StopWatch.cs
new file mode 100644
index 0000000..2ad74a2
--- /dev/null
+++ b/tests/NLog.AsyncBenchmark/StopWatch.cs
@@ -0,0 +1,95 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Threading;
+using System.Globalization;
+using System.IO;
+using System.Xml;
+using System.Runtime.InteropServices;
+
+public class StopWatch
+{
+ private long _startTime;
+ private long _stopTime;
+ private static long _overhead = 0;
+ private static long _frequency;
+
+ static StopWatch()
+ {
+ QueryPerformanceFrequency(out _frequency);
+ StopWatch callibration = new StopWatch();
+ long totalOverhead = 0;
+ int loopCount = 0;
+ for (int i = 0; i < 1000000; ++i)
+ {
+ callibration.Start();
+ callibration.Stop();
+ totalOverhead += callibration.Ticks;
+ loopCount++;
+ }
+ _overhead = totalOverhead / loopCount;
+ //Console.WriteLine("Callibrating StopWatch: overhead {0}", _overhead);
+ }
+
+ public void Start()
+ {
+ QueryPerformanceCounter(out _startTime);
+ }
+
+ public void Stop()
+ {
+ QueryPerformanceCounter(out _stopTime);
+ }
+
+ public long Ticks
+ {
+ get { return _stopTime - _startTime - _overhead; }
+ }
+
+ public double Seconds
+ {
+ get { return (double)(_stopTime - _startTime - _overhead) / _frequency; }
+ }
+
+ public double Nanoseconds
+ {
+ get { return (double)1000000000 * (_stopTime - _startTime - _overhead) / _frequency; }
+ }
+
+ [DllImport("kernel32.dll")]
+ static extern bool QueryPerformanceCounter(out long val);
+
+ [DllImport("kernel32.dll")]
+ static extern bool QueryPerformanceFrequency(out long val);
+}
diff --git a/tests/NLog.Benchmark/Benchmark.cs b/tests/NLog.Benchmark/Benchmark.cs
new file mode 100644
index 0000000..aadbbd7
--- /dev/null
+++ b/tests/NLog.Benchmark/Benchmark.cs
@@ -0,0 +1,376 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Threading;
+using System.Globalization;
+using System.IO;
+using System.Xml;
+using System.Runtime.InteropServices;
+
+using System.Text;
+using System.CodeDom.Compiler;
+
+//
+// distribution - taken from some development sample
+//
+// Debug - 20000
+// Info - 6500
+// Warn - 100
+// Error - 10
+// Fatal - 0
+//
+
+namespace NLog.Benchmark
+{
+ class Program
+ {
+ private static double _overhead = 0.0;
+ private static double _maxmax = 0.0;
+
+ private static string GenerateTestSourceCode(IBenchmark bench)
+ {
+ StringWriter sw = new StringWriter();
+
+ sw.WriteLine("using System;");
+
+ sw.WriteLine(bench.Header);
+
+ sw.WriteLine("public class TheBenchmark {");
+ sw.WriteLine("static TheBenchmark() {");
+ sw.WriteLine("}");
+ sw.WriteLine(bench.CreateSource("logger1", "nosuchlogger"));
+ sw.WriteLine(bench.CreateSource("logger2", "null1"));
+ sw.WriteLine(bench.CreateSource("logger3", "null2"));
+ sw.WriteLine(bench.CreateSource("logger4", "file1"));
+ sw.WriteLine(bench.CreateSource("logger5", "file3"));
+ sw.WriteLine(bench.CreateSource("logger6", "file2"));
+
+ sw.WriteLine("public static void Init() {");
+ //sw.WriteLine("Console.WriteLine(\"Init\");");
+ sw.WriteLine(bench.Init);
+ sw.WriteLine("} // Init()");
+ sw.WriteLine("public static void Flush() {");
+ //sw.WriteLine("Console.WriteLine(\"Flushing\");");
+ sw.WriteLine(bench.Flush);
+ //sw.WriteLine("Console.WriteLine(\"Flushed\");");
+ sw.WriteLine("} // Flush()");
+ sw.WriteLine("public static void DoNothing() {");
+ sw.WriteLine("} // DoNothing()");
+ sw.WriteLine("public static void NoLogging() {");
+ sw.WriteLine(bench.WriteUnformatted("logger1", "Debug", "Lorem Ipsum"));
+ sw.WriteLine(bench.WriteUnformatted("logger1", "Info", "Lorem Ipsum"));
+ sw.WriteLine(bench.WriteUnformatted("logger1", "Warn", "Lorem Ipsum"));
+ sw.WriteLine(bench.WriteUnformatted("logger1", "Error", "Lorem Ipsum"));
+ sw.WriteLine(bench.WriteUnformatted("logger1", "Fatal", "Lorem Ipsum"));
+ sw.WriteLine("}");
+ sw.WriteLine("public static void NoLoggingWithFormatting1() {");
+ sw.WriteLine(bench.WriteFormatted("logger1", "Debug", "Lorem Ipsum", "1"));
+ sw.WriteLine(bench.WriteFormatted("logger1", "Info", "Lorem Ipsum", "2"));
+ sw.WriteLine(bench.WriteFormatted("logger1", "Warn", "Lorem Ipsum", "3"));
+ sw.WriteLine(bench.WriteFormatted("logger1", "Error", "Lorem Ipsum", "4"));
+ sw.WriteLine(bench.WriteFormatted("logger1", "Fatal", "Lorem Ipsum", "5"));
+ sw.WriteLine("}");
+ sw.WriteLine("public static void NoLoggingWithFormatting2() {");
+ sw.WriteLine(bench.WriteFormatted("logger1", "Debug", "Lorem Ipsum", "1,2"));
+ sw.WriteLine(bench.WriteFormatted("logger1", "Info", "Lorem Ipsum", "2,3"));
+ sw.WriteLine(bench.WriteFormatted("logger1", "Warn", "Lorem Ipsum", "3,4"));
+ sw.WriteLine(bench.WriteFormatted("logger1", "Error", "Lorem Ipsum", "4,5"));
+ sw.WriteLine(bench.WriteFormatted("logger1", "Fatal", "Lorem Ipsum", "5,6"));
+ sw.WriteLine("}");
+ sw.WriteLine("public static void NoLoggingWithFormatting3() {");
+ sw.WriteLine(bench.WriteFormatted("logger1", "Debug", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger1", "Info", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger1", "Warn", "Lorem Ipsum", "false,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger1", "Error", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger1", "Fatal", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine("}");
+ sw.WriteLine("public static void GuardedNoLogging() {");
+ sw.WriteLine(bench.GuardedWrite("logger1", "Debug", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine(bench.GuardedWrite("logger1", "Info", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.GuardedWrite("logger1", "Warn", "Lorem Ipsum", "false,2,\"test\""));
+ sw.WriteLine(bench.GuardedWrite("logger1", "Error", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.GuardedWrite("logger1", "Fatal", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine("}");
+ sw.WriteLine("public static void NullLoggingWithoutFormatting() {");
+ sw.WriteLine(bench.WriteUnformatted("logger2", "Debug", "Lorem Ipsum"));
+ sw.WriteLine(bench.WriteUnformatted("logger2", "Info", "Lorem Ipsum"));
+ sw.WriteLine(bench.WriteUnformatted("logger2", "Warn", "Lorem Ipsum"));
+ sw.WriteLine(bench.WriteUnformatted("logger2", "Error", "Lorem Ipsum"));
+ sw.WriteLine(bench.WriteUnformatted("logger2", "Fatal", "Lorem Ipsum"));
+ sw.WriteLine("}");
+ sw.WriteLine("public static void NullLoggingWithFormatting1() {");
+ sw.WriteLine(bench.WriteFormatted("logger2", "Debug", "Lorem Ipsum", "1"));
+ sw.WriteLine(bench.WriteFormatted("logger2", "Info", "Lorem Ipsum", "2"));
+ sw.WriteLine(bench.WriteFormatted("logger2", "Warn", "Lorem Ipsum", "3"));
+ sw.WriteLine(bench.WriteFormatted("logger2", "Error", "Lorem Ipsum", "4"));
+ sw.WriteLine(bench.WriteFormatted("logger2", "Fatal", "Lorem Ipsum", "5"));
+ sw.WriteLine("}");
+ sw.WriteLine("public static void NullLoggingWithFormatting3() {");
+ sw.WriteLine(bench.WriteFormatted("logger2", "Debug", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger2", "Info", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger2", "Warn", "Lorem Ipsum", "false,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger2", "Error", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger2", "Fatal", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine("}");
+ sw.WriteLine("public static void NoRenderingLoggingWithoutFormatting() {");
+ sw.WriteLine(bench.WriteUnformatted("logger3", "Debug", "Lorem Ipsum"));
+ sw.WriteLine(bench.WriteUnformatted("logger3", "Info", "Lorem Ipsum"));
+ sw.WriteLine(bench.WriteUnformatted("logger3", "Warn", "Lorem Ipsum"));
+ sw.WriteLine(bench.WriteUnformatted("logger3", "Error", "Lorem Ipsum"));
+ sw.WriteLine(bench.WriteUnformatted("logger3", "Fatal", "Lorem Ipsum"));
+ sw.WriteLine("}");
+ sw.WriteLine("public static void NoRenderingLoggingWithFormatting1() {");
+ sw.WriteLine(bench.WriteFormatted("logger3", "Debug", "Lorem Ipsum", "1"));
+ sw.WriteLine(bench.WriteFormatted("logger3", "Info", "Lorem Ipsum", "2"));
+ sw.WriteLine(bench.WriteFormatted("logger3", "Warn", "Lorem Ipsum", "3"));
+ sw.WriteLine(bench.WriteFormatted("logger3", "Error", "Lorem Ipsum", "4"));
+ sw.WriteLine(bench.WriteFormatted("logger3", "Fatal", "Lorem Ipsum", "5"));
+ sw.WriteLine("}");
+ sw.WriteLine("public static void NoRenderingLoggingWithFormatting3() {");
+ sw.WriteLine(bench.WriteFormatted("logger3", "Debug", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger3", "Info", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger3", "Warn", "Lorem Ipsum", "false,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger3", "Error", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger3", "Fatal", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine("}");
+ sw.WriteLine("public static void SimpleFile() {");
+ sw.WriteLine(bench.WriteFormatted("logger4", "Debug", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger4", "Info", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger4", "Warn", "Lorem Ipsum", "false,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger4", "Error", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger4", "Fatal", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine("}");
+ sw.WriteLine("public static void BufferedFile() {");
+ sw.WriteLine(bench.WriteFormatted("logger5", "Debug", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger5", "Info", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger5", "Warn", "Lorem Ipsum", "false,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger5", "Error", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger5", "Fatal", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine("}");
+ sw.WriteLine("public static void AsyncFile() {");
+ sw.WriteLine(bench.WriteFormatted("logger6", "Debug", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger6", "Info", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger6", "Warn", "Lorem Ipsum", "false,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger6", "Error", "Lorem Ipsum", "1,2,\"test\""));
+ sw.WriteLine(bench.WriteFormatted("logger6", "Fatal", "Lorem Ipsum", "true,2,\"test\""));
+ sw.WriteLine("}");
+ sw.WriteLine("}");
+ return sw.ToString();
+ }
+
+ delegate void RunDelegate();
+
+ private static double TimeCode(RunDelegate init, RunDelegate run, RunDelegate flush, int count)
+ {
+ int unrollCount = 10;
+ if (init != null)
+ init();
+ run();
+ run();
+ run();
+ StopWatch sw = new StopWatch();
+ sw.Start();
+
+ for (int i = 0; i < count; ++i)
+ {
+ run();
+ run();
+ run();
+ run();
+ run();
+ run();
+ run();
+ run();
+ run();
+ run();
+ }
+ if (flush != null)
+ flush();
+ sw.Stop();
+ return sw.Nanoseconds / (count * unrollCount);
+ }
+
+ private static void TimeAndDiscardUnusual(RunDelegate init, RunDelegate run, RunDelegate flush, int count, int samples, out double min, out double max, out double avg)
+ {
+ double[] times = new double[samples];
+
+ for (int i = 0; i < times.Length; ++i)
+ {
+ times[i] = TimeCode(init, run, flush, count) - _overhead;
+ }
+
+ Array.Sort(times);
+
+ // discard lowest 20% and highest 20%
+
+ int startAt = times.Length * 20 / 100;
+ int endAt = times.Length * 80 / 100;
+
+ max = times[startAt];
+ min = times[startAt];
+ avg = 0.0;
+ int cnt = 0;
+
+ for (int i = startAt; i < endAt; ++i)
+ {
+ max = Math.Max(max, times[i]);
+ min = Math.Min(min, times[i]);
+ avg += times[i];
+ cnt++;
+ }
+
+ avg /= cnt;
+ }
+
+ private static void TimeAndDisplay(string name, XmlTextWriter xtw, RunDelegate init, RunDelegate run, RunDelegate flush, int count, int divider)
+ {
+ double min, max, avg;
+
+ TimeAndDiscardUnusual(init, run, flush, count, 10, out min, out max, out avg);
+ max /= divider;
+ min /= divider;
+ avg /= divider;
+ Console.WriteLine("{0}: min={1}ns max={2}ns avg={3}ns", name, Math.Round(min, 3), Math.Round(max, 3), Math.Round(avg, 3));
+ xtw.WriteStartElement("test");
+ xtw.WriteAttributeString("name", name);
+ xtw.WriteAttributeString("min", Convert.ToInt32(min).ToString());
+ xtw.WriteAttributeString("max", Convert.ToInt32(max).ToString());
+ xtw.WriteAttributeString("avg", Convert.ToInt32(avg).ToString());
+ xtw.WriteEndElement();
+ _maxmax = Math.Max(_maxmax, max);
+ }
+
+ public static int Main(string[] args)
+ {
+ try
+ {
+ XmlTextWriter xtw = new XmlTextWriter("results.xml", Encoding.UTF8);
+ xtw.Formatting = Formatting.Indented;
+
+ xtw.WriteProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"Graph.xsl\"");
+
+ xtw.WriteStartElement("results");
+ // DoBenchmark(xtw, new Log4NetWithFastLoggerBenchmark());
+ DoBenchmark(xtw, new Log4NetBenchmark());
+ DoBenchmark(xtw, new NLogBenchmark());
+ xtw.WriteStartElement("scale");
+ xtw.WriteAttributeString("max", Convert.ToInt32(_maxmax).ToString());
+ xtw.WriteEndElement();
+ xtw.WriteEndElement();
+ xtw.Close();
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("ERROR: {0}", ex);
+ return 1;
+ }
+ }
+
+ private static void DoBenchmark(XmlTextWriter xtw, IBenchmark b)
+ {
+ Microsoft.CSharp.CSharpCodeProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
+
+ Console.WriteLine("Benchmark: {0}", b.Name);
+
+ if (File.Exists("BenchmarkAssembly." + b.Name + ".dll"))
+ File.Delete("BenchmarkAssembly." + b.Name + ".dll");
+
+ CompilerParameters options = new CompilerParameters();
+ options.OutputAssembly = "BenchmarkAssembly." + b.Name + ".dll";
+ options.GenerateInMemory = true;
+ options.GenerateExecutable = false;
+ foreach (string s in b.References)
+ options.ReferencedAssemblies.Add(s);
+ options.CompilerOptions = "/optimize+";
+ //options.IncludeDebugInformation = true;
+
+ string sourceCode = GenerateTestSourceCode(b);
+
+ using (StreamWriter sw = File.CreateText("BenchmarkAssembly." + b.Name + ".cs"))
+ {
+ sw.Write(sourceCode);
+ }
+
+ CompilerResults results = provider.CreateCompiler().CompileAssemblyFromSource(options, sourceCode);
+ foreach (CompilerError ce in results.Errors)
+ {
+ Console.WriteLine("ERROR in line {0}: {1}", ce.Line, ce.ErrorText);
+ }
+ if (results.Errors.Count > 0)
+ {
+ Console.WriteLine("Errors in generated code for " + b.Name + " Ignoring.");
+ return;
+ }
+
+ //Console.WriteLine("Compiled to assembly: {0}", results.CompiledAssembly.FullName);
+ xtw.WriteStartElement("framework");
+ xtw.WriteAttributeString("name", b.Name);
+
+ Type t = results.CompiledAssembly.GetType("TheBenchmark");
+
+ double min, max, avg;
+
+ TimeAndDiscardUnusual(null, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "DoNothing"), null, 100000, 10, out min, out max, out avg);
+ _overhead = min;
+
+ Console.WriteLine("overhead: {0}", _overhead);
+
+ RunDelegate init = (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "Init");
+ RunDelegate flush = (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "Flush");
+
+ init();
+
+ TimeAndDisplay("Guarded no logging", xtw, null, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "GuardedNoLogging"), null, 100000, 5);
+ TimeAndDisplay("Unguarded no logging", xtw, null, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "NoLogging"), null, 100000, 5);
+ TimeAndDisplay("Unguarded no logging with formatting 1", xtw, null, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "NoLoggingWithFormatting1"), null, 10000, 5);
+ TimeAndDisplay("Unguarded no logging with formatting 2", xtw, null, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "NoLoggingWithFormatting2"), null, 10000, 5);
+ TimeAndDisplay("Unguarded no logging with formatting 3", xtw, null, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "NoLoggingWithFormatting3"), null, 10000, 5);
+ TimeAndDisplay("Null target without rendering", xtw, init, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "NoRenderingLoggingWithoutFormatting"), flush, 10000, 5);
+ TimeAndDisplay("Null target without rendering 1", xtw, init, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "NoRenderingLoggingWithFormatting1"), flush, 10000, 5);
+ TimeAndDisplay("Null target without rendering 3", xtw, init, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "NoRenderingLoggingWithFormatting3"), flush, 10000, 5);
+ TimeAndDisplay("Null target with rendering", xtw, init, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "NullLoggingWithoutFormatting"), flush, 1000, 5);
+ TimeAndDisplay("Null target with rendering 1", xtw, init, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "NullLoggingWithFormatting1"), flush, 1000, 5);
+ TimeAndDisplay("Null target with rendering 3", xtw, init, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "NullLoggingWithFormatting3"), flush, 1000, 5);
+ TimeAndDisplay("Simple file", xtw, init, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "SimpleFile"), flush, 10, 5);
+ //TimeAndDisplay("Buffered file", xtw, init, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "BufferedFile"), flush, 100, 5);
+ //TimeAndDisplay("Asynchronous File without a flush", xtw, init, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "AsyncFile"), null, 100, 5);
+ //flush();
+ //TimeAndDisplay("Asynchronous File with a flush", xtw, init, (RunDelegate)Delegate.CreateDelegate(typeof(RunDelegate), t, "AsyncFile"), flush, 5000, 5);
+
+ xtw.WriteEndElement();
+ }
+ }
+
+}
diff --git a/tests/NLog.Benchmark/Graph.xsl b/tests/NLog.Benchmark/Graph.xsl
new file mode 100644
index 0000000..4b809f1
--- /dev/null
+++ b/tests/NLog.Benchmark/Graph.xsl
@@ -0,0 +1,76 @@
+<?xml version="1.0" ?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:variable name="framework_count" select="count(/results/framework)" />
+ <xsl:variable name="scale_max" select="/results/scale/@max" />
+
+ <xsl:template match="/">
+ <html>
+ <head>
+ <title></title>
+ <style>
+ body
+ {
+ font-family: Tahoma;
+ font-size: 80%;
+ }
+
+ table
+ {
+ font-size: 100%;
+ }
+
+ tr.title
+ {
+ background-color: white;
+ font-weight: bold;
+ background-color: #c0c0ff;
+ }
+ tr.graph
+ {
+ background-color: #e0e0ff;
+ }
+
+ td
+ {
+ padding: 2px;
+ }
+ </style>
+ </head>
+ <body>
+ <table border="0" cellspacing="0" width="100%">
+ <xsl:for-each select="/results/framework[position()=1]/test">
+ <xsl:variable name="timing_name" select="@name" />
+
+ <xsl:apply-templates select="//test[@name=$timing_name]">
+ </xsl:apply-templates>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+
+ </xsl:template>
+
+ <xsl:template match="test">
+ <xsl:if test="position() = 1">
+ <tr class="title">
+ <td colspan="3">
+ <xsl:value-of select="@name" />
+ </td>
+ </tr>
+ </xsl:if>
+ <tr class="graph">
+ <td width="1%">
+ <xsl:value-of select="../@name" />
+ </td>
+ <td width="1%">
+ <xsl:value-of select="@avg" />
+ </td>
+ <td width="100%">
+ <xsl:variable name="pixels" select="100 * (@avg div $scale_max)" />
+ <div style="border: 1px solid #606060; width: {$pixels}%; height: 12px">
+ <img src="bar_{../@name}.png" style="width: 100%; height: 12px" />
+ </div>
+ </td>
+ </tr>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/tests/NLog.Benchmark/IBenchmark.cs b/tests/NLog.Benchmark/IBenchmark.cs
new file mode 100644
index 0000000..98a2828
--- /dev/null
+++ b/tests/NLog.Benchmark/IBenchmark.cs
@@ -0,0 +1,56 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Threading;
+using System.Globalization;
+using System.IO;
+using System.Xml;
+using System.Runtime.InteropServices;
+
+namespace NLog.Benchmark
+{
+ public interface IBenchmark
+ {
+ string Name { get; }
+ string[] References { get; }
+ string Header { get; }
+ string Footer { get; }
+ string Init { get; }
+ string Flush { get; }
+ string CreateSource(string variableName, string name);
+ string WriteUnformatted(string loggerVariable, string level, string text);
+ string WriteFormatted(string loggerVariable, string level, string text, string par);
+ string GuardedWrite(string loggerVariable, string level, string text, string par);
+ }
+}
\ No newline at end of file
diff --git a/tests/NLog.Benchmark/Log4NetBenchmark.cs b/tests/NLog.Benchmark/Log4NetBenchmark.cs
new file mode 100644
index 0000000..87baf32
--- /dev/null
+++ b/tests/NLog.Benchmark/Log4NetBenchmark.cs
@@ -0,0 +1,252 @@
+using NLog;
+
+namespace NLog.Benchmark
+{
+ class Log4NetBenchmark : IBenchmark
+ {
+ protected virtual string ConfigFile
+ {
+ get { return "log4net.config"; }
+ }
+
+ protected string Log4NetCommonHeader
+ {
+ get {
+ return @"using log4net;
+
+using log4net.Config;
+using log4net.Core;
+using log4net.Appender;
+using log4net.Util;
+using System.Threading;
+
+[assembly: XmlConfigurator(ConfigFile=""" + ConfigFile + @""")]
+
+public class NullAppender : AppenderSkeleton
+{
+ override protected void Append(LoggingEvent loggingEvent)
+ {
+ }
+}
+
+public class NullAppenderWithLayout : AppenderSkeleton
+{
+ override protected void Append(LoggingEvent loggingEvent)
+ {
+ RenderLoggingEvent(loggingEvent);
+ }
+}
+
+public sealed class AsyncAppender : IAppender, IBulkAppender, IOptionHandler, IAppenderAttachable
+{
+ private string m_name;
+
+ public string Name
+ {
+ get { return m_name; }
+ set { m_name = value; }
+ }
+
+ public void ActivateOptions()
+ {
+ }
+
+ public FixFlags Fix
+ {
+ get { return m_fixFlags; }
+ set { m_fixFlags = value; }
+ }
+
+ public void Close()
+ {
+ // Remove all the attached appenders
+ lock(this)
+ {
+ if (m_appenderAttachedImpl != null)
+ {
+ m_appenderAttachedImpl.RemoveAllAppenders();
+ }
+ }
+ }
+
+ public void DoAppend(LoggingEvent loggingEvent)
+ {
+ loggingEvent.Fix = m_fixFlags;
+ System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncAppend), loggingEvent);
+ }
+
+ public void DoAppend(LoggingEvent[] loggingEvents)
+ {
+ foreach(LoggingEvent loggingEvent in loggingEvents)
+ {
+ loggingEvent.Fix = m_fixFlags;
+ }
+ System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncAppend), loggingEvents);
+ }
+
+ private void AsyncAppend(object state)
+ {
+ if (m_appenderAttachedImpl != null)
+ {
+ LoggingEvent loggingEvent = state as LoggingEvent;
+ if (loggingEvent != null)
+ {
+ m_appenderAttachedImpl.AppendLoopOnAppenders(loggingEvent);
+ }
+ else
+ {
+ LoggingEvent[] loggingEvents = state as LoggingEvent[];
+ if (loggingEvents != null)
+ {
+ m_appenderAttachedImpl.AppendLoopOnAppenders(loggingEvents);
+ }
+ }
+ }
+ }
+
+ public void AddAppender(IAppender newAppender)
+ {
+ if (newAppender == null)
+ {
+ throw new ArgumentNullException(""newAppender"");
+ }
+ lock(this)
+ {
+ if (m_appenderAttachedImpl == null)
+ {
+ m_appenderAttachedImpl = new log4net.Util.AppenderAttachedImpl();
+ }
+ m_appenderAttachedImpl.AddAppender(newAppender);
+ }
+ }
+
+ public AppenderCollection Appenders
+ {
+ get
+ {
+ lock(this)
+ {
+ if (m_appenderAttachedImpl == null)
+ {
+ return AppenderCollection.EmptyCollection;
+ }
+ else
+ {
+ return m_appenderAttachedImpl.Appenders;
+ }
+ }
+ }
+ }
+
+ public IAppender GetAppender(string name)
+ {
+ lock(this)
+ {
+ if (m_appenderAttachedImpl == null || name == null)
+ {
+ return null;
+ }
+
+ return m_appenderAttachedImpl.GetAppender(name);
+ }
+ }
+
+ public void RemoveAllAppenders()
+ {
+ lock(this)
+ {
+ if (m_appenderAttachedImpl != null)
+ {
+ m_appenderAttachedImpl.RemoveAllAppenders();
+ m_appenderAttachedImpl = null;
+ }
+ }
+ }
+
+ public IAppender RemoveAppender(IAppender appender)
+ {
+ lock(this)
+ {
+ if (appender != null && m_appenderAttachedImpl != null)
+ {
+ return m_appenderAttachedImpl.RemoveAppender(appender);
+ }
+ }
+ return null;
+ }
+
+ public IAppender RemoveAppender(string name)
+ {
+ lock(this)
+ {
+ if (name != null && m_appenderAttachedImpl != null)
+ {
+ return m_appenderAttachedImpl.RemoveAppender(name);
+ }
+ }
+ return null;
+ }
+
+ private AppenderAttachedImpl m_appenderAttachedImpl;
+ private FixFlags m_fixFlags = FixFlags.All;
+}
+";
+ }
+ }
+
+ public virtual string Header
+ {
+ get {
+ return Log4NetCommonHeader;
+ }
+ }
+
+ public string Footer
+ {
+ get
+ {
+ return "";
+ }
+ }
+
+ public virtual string CreateSource(string variableName, string name)
+ {
+ return "static ILog " + variableName + " = LogManager.GetLogger(\"" + name + "\");";
+ }
+
+ public string WriteUnformatted(string loggerVariable, string level, string text)
+ {
+ return loggerVariable + "." + level + "(\"" + text + "\");";
+ }
+
+ public string WriteFormatted(string loggerVariable, string level, string text, string par)
+ {
+ return loggerVariable + "." + level + "Format(\"" + text + "\", " + par + ");";
+ }
+
+ public string GuardedWrite(string loggerVariable, string level, string text, string par)
+ {
+ return "if (" + loggerVariable + ".Is" + level + "Enabled) " + loggerVariable + "." + level + "Format(\"" + text + "\", " + par + ");";
+ }
+
+ public string[] References
+ {
+ get { return new string[] { "log4net.dll", "System.dll", "System.Xml.dll" }; }
+ }
+
+ public virtual string Name
+ {
+ get { return "Log4Net"; }
+ }
+
+ public virtual string Init
+ {
+ get { return "log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(\"Log4Net.config\"));"; }
+ }
+
+ public string Flush
+ {
+ get { return "LogManager.Shutdown();"; }
+ }
+ }
+}
diff --git a/tests/NLog.Benchmark/Log4NetWithFastLogger.config b/tests/NLog.Benchmark/Log4NetWithFastLogger.config
new file mode 100644
index 0000000..40f1f88
--- /dev/null
+++ b/tests/NLog.Benchmark/Log4NetWithFastLogger.config
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<log4net>
+ <appender name="file1" type="log4net.Appender.FileAppender">
+ <file value="log4net-log.txt" />
+ <layout type="log4net.Layout.PatternLayout,log4net">
+ <conversionPattern value="%level %d %m%n" />
+ </layout>
+ </appender>
+
+ <appender name="file2" type="AsyncAppender, BenchmarkAssembly.Log4NetWithFastLogger">
+ <appender-ref ref="file2wrapped" />
+ </appender>
+
+ <appender name="file2wrapped" type="log4net.Appender.FileAppender">
+ <file value="log4net2-log.txt" />
+ <layout type="log4net.Layout.PatternLayout,log4net">
+ <conversionPattern value="%level %d %m%n" />
+ </layout>
+ </appender>
+
+ <appender name="file3" type="log4net.Appender.BufferingForwardingAppender">
+ <appender-ref ref="file3wrapped" />
+ </appender>
+
+ <appender name="file3wrapped" type="log4net.Appender.FileAppender">
+ <file value="log4net3-log.txt" />
+ <layout type="log4net.Layout.PatternLayout,log4net">
+ <conversionPattern value="%level %d %m%n" />
+ </layout>
+ </appender>
+
+ <appender name="null1" type="NullAppenderWithLayout,BenchmarkAssembly.Log4NetWithFastLogger">
+ <layout type="log4net.Layout.PatternLayout,log4net">
+ <conversionPattern value="%level %d %m%n" />
+ </layout>
+ </appender>
+
+ <appender name="null2" type="NullAppender,BenchmarkAssembly.Log4NetWithFastLogger">
+ <layout type="log4net.Layout.PatternLayout,log4net">
+ <conversionPattern value="%level %d %m%n" />
+ </layout>
+ </appender>
+
+ <logger name="null2">
+ <level value="DEBUG" />
+ <appender-ref ref="null2" />
+ </logger>
+
+ <logger name="null1">
+ <level value="DEBUG" />
+ <appender-ref ref="null1" />
+ </logger>
+
+ <logger name="file1">
+ <level value="DEBUG" />
+ <appender-ref ref="file1" />
+ </logger>
+
+ <logger name="file2">
+ <level value="DEBUG" />
+ <appender-ref ref="file2" />
+ </logger>
+
+ <logger name="file3">
+ <level value="DEBUG" />
+ <appender-ref ref="file3" />
+ </logger>
+
+ <root>
+ <level value="OFF" />
+ </root>
+</log4net>
+
diff --git a/tests/NLog.Benchmark/Log4NetWithFastLoggerBenchmark.cs b/tests/NLog.Benchmark/Log4NetWithFastLoggerBenchmark.cs
new file mode 100644
index 0000000..0ab4473
--- /dev/null
+++ b/tests/NLog.Benchmark/Log4NetWithFastLoggerBenchmark.cs
@@ -0,0 +1,154 @@
+using NLog;
+
+namespace NLog.Benchmark
+{
+ class Log4NetWithFastLoggerBenchmark : Log4NetBenchmark
+ {
+ protected override string ConfigFile
+ {
+ get
+ {
+ return "Log4NetWithFastLogger.config";
+ }
+ }
+
+ public override string Header
+ {
+ get
+ {
+ return @"using System.Reflection;
+using System.Globalization;
+" + base.Log4NetCommonHeader + @"
+
+public sealed class FastLogger : LoggerWrapperImpl
+{
+ private readonly static Type declaringType = typeof(FastLogger);
+ public FastLogger(ILogger logger) : base(logger)
+ {
+
+ }
+
+ public bool IsDebugEnabled
+ {
+ get { return Logger.IsEnabledFor(Level.Debug); }
+ }
+
+ public void Debug(string message)
+ {
+ Logger.Log(declaringType, Level.Debug, message, null);
+ }
+ public void DebugFormat(string format, params object[] args)
+ {
+ if (Logger.IsEnabledFor(Level.Debug))
+ {
+ Logger.Log(declaringType, Level.Debug, String.Format(CultureInfo.InvariantCulture, format, args), null);
+ }
+ }
+
+ public bool IsInfoEnabled
+ {
+ get { return Logger.IsEnabledFor(Level.Info); }
+ }
+
+ public void Info(string message)
+ {
+ Logger.Log(declaringType, Level.Info, message, null);
+ }
+ public void InfoFormat(string format, params object[] args)
+ {
+ if (Logger.IsEnabledFor(Level.Info))
+ {
+ Logger.Log(declaringType, Level.Info, String.Format(CultureInfo.InvariantCulture, format, args), null);
+ }
+ }
+
+ public bool IsWarnEnabled
+ {
+ get { return Logger.IsEnabledFor(Level.Warn); }
+ }
+
+ public void Warn(string message)
+ {
+ Logger.Log(declaringType, Level.Warn, message, null);
+ }
+ public void WarnFormat(string format, params object[] args)
+ {
+ if (Logger.IsEnabledFor(Level.Warn))
+ {
+ Logger.Log(declaringType, Level.Warn, String.Format(CultureInfo.InvariantCulture, format, args), null);
+ }
+ }
+
+ public bool IsErrorEnabled
+ {
+ get { return Logger.IsEnabledFor(Level.Error); }
+ }
+
+ public void Error(string message)
+ {
+ Logger.Log(declaringType, Level.Error, message, null);
+ }
+ public void ErrorFormat(string format, params object[] args)
+ {
+ if (Logger.IsEnabledFor(Level.Error))
+ {
+ Logger.Log(declaringType, Level.Error, String.Format(CultureInfo.InvariantCulture, format, args), null);
+ }
+ }
+
+ public bool IsFatalEnabled
+ {
+ get { return Logger.IsEnabledFor(Level.Fatal); }
+ }
+
+ public void Fatal(string message)
+ {
+ Logger.Log(declaringType, Level.Fatal, message, null);
+ }
+ public void FatalFormat(string format, params object[] args)
+ {
+ if (Logger.IsEnabledFor(Level.Fatal))
+ {
+ Logger.Log(declaringType, Level.Fatal, String.Format(CultureInfo.InvariantCulture, format, args), null);
+ }
+ }
+
+}
+
+public sealed class FastLoggerLogManager
+{
+ private static readonly WrapperMap s_wrapperMap = new WrapperMap(
+ new WrapperCreationHandler(WrapperCreationHandler));
+ private FastLoggerLogManager()
+ {
+
+ }
+ public static FastLogger GetLogger(string name)
+ {
+ return (FastLogger)s_wrapperMap.GetWrapper(
+ LoggerManager.GetLogger(Assembly.GetCallingAssembly(), name));
+ }
+ private static ILoggerWrapper WrapperCreationHandler(ILogger logger)
+ {
+ return new FastLogger(logger);
+ }
+}
+";
+ }
+ }
+
+ public override string CreateSource(string variableName, string name)
+ {
+ return "static FastLogger " + variableName + " = FastLoggerLogManager.GetLogger(\"" + name + "\");";
+ }
+
+ public override string Name
+ {
+ get { return "Log4NetWithFastLogger"; }
+ }
+ public override string Init
+ {
+ get { return "log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(\"Log4NetWithFastLogger.config\"));"; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/NLog.Benchmark/NLog.Benchmark.vs2003.csproj b/tests/NLog.Benchmark/NLog.Benchmark.vs2003.csproj
new file mode 100644
index 0000000..e445101
--- /dev/null
+++ b/tests/NLog.Benchmark/NLog.Benchmark.vs2003.csproj
@@ -0,0 +1,124 @@
+<VisualStudioProject>
+ <CSHARP
+ ProjectType = "Local"
+ ProductVersion = "7.10.3077"
+ SchemaVersion = "2.0"
+ ProjectGuid = "{842A5DA9-BA2B-4934-8ED6-2E6495F7476D}"
+ >
+ <Build>
+ <Settings
+ ApplicationIcon = ""
+ AssemblyKeyContainerName = ""
+ AssemblyName = "NLog.Benchmark"
+ AssemblyOriginatorKeyFile = ""
+ DefaultClientScript = "JScript"
+ DefaultHTMLPageLayout = "Grid"
+ DefaultTargetSchema = "IE50"
+ DelaySign = "false"
+ OutputType = "Exe"
+ PreBuildEvent = ""
+ PostBuildEvent = 'copy "$(ProjectDir)\*.config" "$(TargetDir)"
copy "$(ProjectDir)\*.xsl" "$(TargetDir)"
copy "$(ProjectDir)\*.png" "$(TargetDir)"'
+ RootNamespace = "NLog.Benchmark"
+ RunPostBuildEvent = "OnBuildSuccess"
+ StartupObject = ""
+ >
+ <Config
+ Name = "Debug"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = ""
+ DocumentationFile = ""
+ DebugSymbols = "true"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = ""
+ Optimize = "false"
+ OutputPath = "bin\Debug\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "1"
+ />
+ <Config
+ Name = "Release"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = ""
+ DocumentationFile = ""
+ DebugSymbols = "false"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = ""
+ Optimize = "false"
+ OutputPath = "bin\Release\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "1"
+ />
+ </Settings>
+ <References>
+ <Reference
+ Name = "NLog"
+ Project = "{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+ Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+ />
+ <Reference
+ Name = "System.XML"
+ AssemblyName = "System.Xml"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
+ />
+ <Reference
+ Name = "System"
+ AssemblyName = "System"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll"
+ />
+ </References>
+ </Build>
+ <Files>
+ <Include>
+ <File
+ RelPath = "Benchmark.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "IBenchmark.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Log4NetBenchmark.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Log4NetWithFastLoggerBenchmark.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "NLog.config"
+ BuildAction = "None"
+ />
+ <File
+ RelPath = "NLogBenchmark.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "StopWatch.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ </Include>
+ </Files>
+ </CSHARP>
+</VisualStudioProject>
+
diff --git a/tests/NLog.Benchmark/NLog.Benchmark.vs2005.csproj b/tests/NLog.Benchmark/NLog.Benchmark.vs2005.csproj
new file mode 100644
index 0000000..9fd2bcc
--- /dev/null
+++ b/tests/NLog.Benchmark/NLog.Benchmark.vs2005.csproj
@@ -0,0 +1,133 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectType>Local</ProjectType>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{842A5DA9-BA2B-4934-8ED6-2E6495F7476D}</ProjectGuid>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ApplicationIcon>
+ </ApplicationIcon>
+ <AssemblyKeyContainerName>
+ </AssemblyKeyContainerName>
+ <AssemblyName>NLog.Benchmark</AssemblyName>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <DefaultClientScript>JScript</DefaultClientScript>
+ <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+ <DefaultTargetSchema>IE50</DefaultTargetSchema>
+ <DelaySign>false</DelaySign>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>NLog.Benchmark</RootNamespace>
+ <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+ <StartupObject>
+ </StartupObject>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <OutputPath>bin\Debug\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>
+ </DefineConstants>
+ <DocumentationFile>
+ </DocumentationFile>
+ <DebugSymbols>true</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>
+ </NoWarn>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>1</WarningLevel>
+ <DebugType>full</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <OutputPath>bin\Release\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>
+ </DefineConstants>
+ <DocumentationFile>
+ </DocumentationFile>
+ <DebugSymbols>false</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>
+ </NoWarn>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>1</WarningLevel>
+ <DebugType>none</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\NLog\NLog.vs2005.csproj">
+ <Name>NLog.vs2005</Name>
+ <Project>{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}</Project>
+ <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
+ </ProjectReference>
+ <Reference Include="System" />
+ <Reference Include="System.Xml">
+ <Name>System.XML</Name>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Benchmark.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Log4NetWithFastLoggerBenchmark.cs" />
+ <Compile Include="Log4NetBenchmark.cs" />
+ <Compile Include="NLogBenchmark.cs" />
+ <Compile Include="IBenchmark.cs" />
+ <Compile Include="StopWatch.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Log4NetWithFastLogger.config">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
+ <None Include="Log4Net.config">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
+ <None Include="NLog.config">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="bar_Log4Net.png">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="bar_Log4NetWithFastLogger.png">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="bar_NLog.png">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Graph.xsl">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>
+ </PreBuildEvent>
+ <PostBuildEvent>
+ </PostBuildEvent>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/tests/NLog.Benchmark/NLog.config b/tests/NLog.Benchmark/NLog.config
new file mode 100644
index 0000000..fa03d03
--- /dev/null
+++ b/tests/NLog.Benchmark/NLog.config
@@ -0,0 +1,36 @@
+<?xml version="1.0" ?>
+<configuration>
+ <configSections>
+ <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
+ </configSections>
+ <nlog autoReload="true" xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <targets>
+ <target name="file1" xsi:type="File" fileName="nlog-log.txt" layout="${level} ${longdate} ${message}" concurrentWrites="false" keepFileOpen="true" />
+ <target name="file2" xsi:type="AsyncWrapper" overflowAction="Grow">
+ <target xsi:type="File" fileName="nlog2-log.txt" layout="${level} ${longdate} ${message}" concurrentWrites="false" keepFileOpen="true" />
+ </target>
+ <target name="file3" xsi:type="BufferingWrapper" bufferSize="10000">
+ <target xsi:type="File" fileName="nlog3-log.txt" layout="${level} ${longdate} ${message}" concurrentWrites="false" keepFileOpen="true" />
+ </target>
+ <target name="null1" xsi:type="Null" formatMessage="true" layout="${level} ${longdate} ${message}" />
+ <target name="null2" xsi:type="Null" layout="${level} ${longdate} ${message}" />
+ <target name="archive1" xsi:type="File" fileName="arch1-file.txt" concurrentWrites="false" archiveAboveSize="100000000" />
+ <target name="archive2" xsi:type="File" fileName="arch2-file.txt" concurrentWrites="false" archiveAboveSize="10000" />
+ <target name="archive3" xsi:type="File" fileName="arch3-file.txt" concurrentWrites="true" archiveAboveSize="100000000" />
+ <target name="archive4" xsi:type="File" fileName="arch4-file.txt" concurrentWrites="true" archiveAboveSize="10000" />
+ </targets>
+
+ <rules>
+ <logger name="nonlogger" minlevel="Fatal" writeTo="null1" />
+ <logger name="file1" minlevel="Debug" writeTo="file1" />
+ <logger name="file2" minlevel="Debug" writeTo="file2" />
+ <logger name="file3" minlevel="Debug" writeTo="file3" />
+ <logger name="null1" minlevel="Debug" writeTo="null1" />
+ <logger name="null2" minlevel="Debug" writeTo="null2" />
+ <logger name="archive1" minlevel="Debug" writeTo="archive1" />
+ <logger name="archive2" minlevel="Debug" writeTo="archive2" />
+ <logger name="archive3" minlevel="Debug" writeTo="archive3" />
+ <logger name="archive4" minlevel="Debug" writeTo="archive4" />
+ </rules>
+ </nlog>
+</configuration>
diff --git a/tests/NLog.Benchmark/NLogBenchmark.cs b/tests/NLog.Benchmark/NLogBenchmark.cs
new file mode 100644
index 0000000..1cc5b93
--- /dev/null
+++ b/tests/NLog.Benchmark/NLogBenchmark.cs
@@ -0,0 +1,63 @@
+using NLog;
+
+namespace NLog.Benchmark
+{
+ class NLogBenchmark : IBenchmark
+ {
+ public string Header
+ {
+ get {
+ return @"using NLog;
+using NLog.Config;";
+ }
+ }
+
+ public string Footer
+ {
+ get
+ {
+ return "";
+ }
+ }
+
+ public string CreateSource(string variableName, string name)
+ {
+ return "static Logger " + variableName + " = LogManager.GetLogger(\"" + name + "\");";
+ }
+
+ public string WriteUnformatted(string loggerVariable, string level, string text)
+ {
+ return loggerVariable + "." + level + "(\"" + text + "\");";
+ }
+
+ public string WriteFormatted(string loggerVariable, string level, string text, string par)
+ {
+ return loggerVariable + "." + level + "(\"" + text + "\", " + par + ");";
+ }
+
+ public string GuardedWrite(string loggerVariable, string level, string text, string par)
+ {
+ return "if (" + loggerVariable + ".Is" + level + "Enabled) " + loggerVariable + "." + level + "(\"" + text + "\", " + par + ");";
+ }
+
+ public string[] References
+ {
+ get { return new string[] { "NLog.dll" }; }
+ }
+
+ public string Name
+ {
+ get { return "NLog"; }
+ }
+
+ public string Init
+ {
+ get { return "LogManager.Configuration = new XmlLoggingConfiguration(\"NLog.config\");"; }
+ }
+
+ public string Flush
+ {
+ get { return "LogManager.Flush();"; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/NLog.Benchmark/StopWatch.cs b/tests/NLog.Benchmark/StopWatch.cs
new file mode 100644
index 0000000..b3fafd7
--- /dev/null
+++ b/tests/NLog.Benchmark/StopWatch.cs
@@ -0,0 +1,83 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Threading;
+using System.Globalization;
+using System.IO;
+using System.Xml;
+using System.Runtime.InteropServices;
+using System.Security;
+
+public class StopWatch
+{
+ private long _startTime;
+ private long _stopTime;
+ private static long _frequency;
+
+ static StopWatch()
+ {
+ QueryPerformanceFrequency(out _frequency);
+ }
+
+ public void Start()
+ {
+ QueryPerformanceCounter(out _startTime);
+ }
+
+ public void Stop()
+ {
+ QueryPerformanceCounter(out _stopTime);
+ }
+
+ public long Ticks
+ {
+ get { return _stopTime - _startTime; }
+ }
+
+ public double Seconds
+ {
+ get { return (double)(_stopTime - _startTime) / _frequency; }
+ }
+
+ public double Nanoseconds
+ {
+ get { return (double)1000000000 * (_stopTime - _startTime) / _frequency; }
+ }
+
+ [DllImport("kernel32.dll"),SuppressUnmanagedCodeSecurity]
+ static extern bool QueryPerformanceCounter(out long val);
+
+ [DllImport("kernel32.dll"),SuppressUnmanagedCodeSecurity]
+ static extern bool QueryPerformanceFrequency(out long val);
+}
diff --git a/tests/NLog.Benchmark/bar_Log4Net.png b/tests/NLog.Benchmark/bar_Log4Net.png
new file mode 100644
index 0000000..c359231
Binary files /dev/null and b/tests/NLog.Benchmark/bar_Log4Net.png differ
diff --git a/tests/NLog.Benchmark/bar_Log4NetWithFastLogger.png b/tests/NLog.Benchmark/bar_Log4NetWithFastLogger.png
new file mode 100644
index 0000000..8ebb7a4
Binary files /dev/null and b/tests/NLog.Benchmark/bar_Log4NetWithFastLogger.png differ
diff --git a/tests/NLog.Benchmark/bar_NLog.png b/tests/NLog.Benchmark/bar_NLog.png
new file mode 100644
index 0000000..5b30da0
Binary files /dev/null and b/tests/NLog.Benchmark/bar_NLog.png differ
diff --git a/tests/NLog.Benchmark/entliblab.config b/tests/NLog.Benchmark/entliblab.config
new file mode 100644
index 0000000..900b357
--- /dev/null
+++ b/tests/NLog.Benchmark/entliblab.config
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<configuration>
+ <configSections>
+ <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
+ </configSections>
+ <loggingConfiguration name="Logging Application Block" tracingEnabled="false"
+ defaultCategory="" logWarningsWhenNoCategoriesMatch="false">
+ <listeners>
+ <add fileName="entlib-log.txt" header="" footer="" formatter="file formatter"
+ listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
+ traceOutputOptions="None" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
+ name="file1" />
+ </listeners>
+ <formatters>
+ <add template="{severity} {timestamp} {message}" type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
+ name="file formatter" />
+ </formatters>
+ <categorySources>
+ <add switchValue="Verbose" name="file1">
+ <listeners>
+ <add name="file1" />
+ </listeners>
+ </add>
+ <add switchValue="Verbose" name="file2" />
+ <add switchValue="Verbose" name="file3" />
+ <add switchValue="Error" name="nonlogger" />
+ <add switchValue="Verbose" name="null1" />
+ <add switchValue="Verbose" name="null2" />
+ </categorySources>
+ <specialSources>
+ <allEvents switchValue="All" name="All Events" />
+ <notProcessed switchValue="All" name="Unprocessed Category" />
+ <errors switchValue="All" name="Logging Errors & Warnings" />
+ </specialSources>
+ </loggingConfiguration>
+</configuration>
\ No newline at end of file
diff --git a/tests/NLog.Benchmark/log4net.config b/tests/NLog.Benchmark/log4net.config
new file mode 100644
index 0000000..326a469
--- /dev/null
+++ b/tests/NLog.Benchmark/log4net.config
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<log4net>
+ <appender name="file1" type="log4net.Appender.FileAppender">
+ <file value="log4net-log.txt" />
+ <layout type="log4net.Layout.PatternLayout,log4net">
+ <conversionPattern value="%level %d %m%n" />
+ </layout>
+ </appender>
+
+ <appender name="file2" type="AsyncAppender, BenchmarkAssembly.log4net">
+ <appender-ref ref="file2wrapped" />
+ </appender>
+
+ <appender name="file2wrapped" type="log4net.Appender.FileAppender">
+ <file value="log4net2-log.txt" />
+ <layout type="log4net.Layout.PatternLayout,log4net">
+ <conversionPattern value="%level %d %m%n" />
+ </layout>
+ </appender>
+
+ <appender name="file3" type="log4net.Appender.BufferingForwardingAppender">
+ <appender-ref ref="file3wrapped" />
+ </appender>
+
+ <appender name="file3wrapped" type="log4net.Appender.FileAppender">
+ <file value="log4net3-log.txt" />
+ <layout type="log4net.Layout.PatternLayout,log4net">
+ <conversionPattern value="%level %d %m%n" />
+ </layout>
+ </appender>
+
+ <appender name="null1" type="NullAppenderWithLayout,BenchmarkAssembly.log4net">
+ <layout type="log4net.Layout.PatternLayout,log4net">
+ <conversionPattern value="%level %d %m%n" />
+ </layout>
+ </appender>
+
+ <appender name="null2" type="NullAppender,BenchmarkAssembly.log4net">
+ <layout type="log4net.Layout.PatternLayout,log4net">
+ <conversionPattern value="%level %d %m%n" />
+ </layout>
+ </appender>
+
+ <logger name="null2">
+ <level value="DEBUG" />
+ <appender-ref ref="null2" />
+ </logger>
+
+ <logger name="null1">
+ <level value="DEBUG" />
+ <appender-ref ref="null1" />
+ </logger>
+
+ <logger name="file1">
+ <level value="DEBUG" />
+ <appender-ref ref="file1" />
+ </logger>
+
+ <logger name="file2">
+ <level value="DEBUG" />
+ <appender-ref ref="file2" />
+ </logger>
+
+ <logger name="file3">
+ <level value="DEBUG" />
+ <appender-ref ref="file3" />
+ </logger>
+
+ <root>
+ <level value="OFF" />
+ </root>
+</log4net>
+
diff --git a/tests/NLog.CFTest/AssemblyInfo.cs b/tests/NLog.CFTest/AssemblyInfo.cs
new file mode 100644
index 0000000..fb77210
--- /dev/null
+++ b/tests/NLog.CFTest/AssemblyInfo.cs
@@ -0,0 +1,84 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.0.0")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+// (*) If no key is specified - the assembly cannot be signed.
+// (*) KeyName refers to a key that has been installed in the Crypto Service
+// Provider (CSP) on your machine.
+// (*) If the key file and a key name attributes are both specified, the
+// following processing occurs:
+// (1) If the KeyName can be found in the CSP - that key is used.
+// (2) If the KeyName does not exist and the KeyFile does exist, the key
+// in the file is installed into the CSP and used.
+// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+// documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]
diff --git a/tests/NLog.CFTest/Form1.cs b/tests/NLog.CFTest/Form1.cs
new file mode 100644
index 0000000..dda1f67
--- /dev/null
+++ b/tests/NLog.CFTest/Form1.cs
@@ -0,0 +1,104 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Drawing;
+using System.Collections;
+using System.Windows.Forms;
+using System.Data;
+
+using NLog;
+
+namespace NLog.CFTest
+{
+ /// <summary>
+ /// Summary description for Form1.
+ /// </summary>
+ public class Form1 : System.Windows.Forms.Form
+ {
+ private static Logger logger = LogManager.GetLogger("LoggerName");
+
+ private System.Windows.Forms.MainMenu mainMenu1;
+
+ public Form1()
+ {
+ //
+ // Required for Windows Form Designer support
+ //
+ InitializeComponent();
+
+ //
+ // TODO: Add any constructor code after InitializeComponent call
+ //
+ }
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ protected override void Dispose( bool disposing )
+ {
+ base.Dispose( disposing );
+ }
+ #region Windows Form Designer generated code
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.mainMenu1 = new System.Windows.Forms.MainMenu();
+ //
+ // Form1
+ //
+ this.Menu = this.mainMenu1;
+ this.Text = "Form1";
+ this.Load += new System.EventHandler(this.Form1_Load);
+
+ }
+ #endregion
+
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+
+ static void Main()
+ {
+ Application.Run(new Form1());
+ }
+
+ private void Form1_Load(object sender, System.EventArgs e)
+ {
+ logger.Error("hello!");
+ Close();
+ }
+ }
+}
diff --git a/tests/NLog.CFTest/Form1.resx b/tests/NLog.CFTest/Form1.resx
new file mode 100644
index 0000000..67084bd
--- /dev/null
+++ b/tests/NLog.CFTest/Form1.resx
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 1.3
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">1.3</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1">this is my long string</data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ [base64 mime encoded serialized .NET Framework object]
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ [base64 mime encoded string representing a byte array form of the .NET Framework object]
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used forserialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>1.3</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Windows.Forms.Design.CFResXResourceReader, System.CF.Design, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Windows.Forms.Design.CFResXResourceWriter, System.CF.Design, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+ </resheader>
+ <data name="mainMenu1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>Private</value>
+ </data>
+ <data name="mainMenu1.Location" type="System.Drawing.Point, System.CF.Drawing, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>17, 17</value>
+ </data>
+ <data name="mainMenu1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>Private</value>
+ </data>
+ <data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>False</value>
+ </data>
+ <data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>(Default)</value>
+ </data>
+ <data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>False</value>
+ </data>
+ <data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>False</value>
+ </data>
+ <data name="$this.GridSize" type="System.Drawing.Size, System.CF.Drawing, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>8, 8</value>
+ </data>
+ <data name="$this.Name">
+ <value>Form1</value>
+ </data>
+ <data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>True</value>
+ </data>
+ <data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>80</value>
+ </data>
+ <data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>True</value>
+ </data>
+ <data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>Private</value>
+ </data>
+</root>
\ No newline at end of file
diff --git a/tests/NLog.CFTest/NLog.CFTest.exe.nlog b/tests/NLog.CFTest/NLog.CFTest.exe.nlog
new file mode 100644
index 0000000..9d942fe
--- /dev/null
+++ b/tests/NLog.CFTest/NLog.CFTest.exe.nlog
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?>
+<nlog internalLogFile="internalLog.txt" internalLogLevel="Debug">
+ <!-- deploy this file to "\Program Files\NLog.CFTest" directory on your device -->
+ <appenders async="true">
+ <appender name="file" type="File" filename="${basedir}/file.txt" />
+ <appender name="network" type="Network" address="udp://jaakntb:5555" />
+ </appenders>
+
+ <rules>
+ <logger name="*" minlevel="Error" appendTo="file,network" />
+ </rules>
+</nlog>
diff --git a/tests/NLog.CFTest/NLog.CFTest.vs2003.csdproj b/tests/NLog.CFTest/NLog.CFTest.vs2003.csdproj
new file mode 100644
index 0000000..e836f87
--- /dev/null
+++ b/tests/NLog.CFTest/NLog.CFTest.vs2003.csdproj
@@ -0,0 +1,158 @@
+<VisualStudioProject>
+ <ECSHARP
+ ProjectType = "Local"
+ ProductVersion = "7.10.3077"
+ SchemaVersion = "1.0"
+ ProjectGuid = "{F8DA3276-560A-490C-AF75-E27307887CA3}"
+ >
+ <Build>
+ <Settings
+ ApplicationIcon = ""
+ AssemblyKeyContainerName = ""
+ AssemblyName = "NLog.CFTest"
+ AssemblyOriginatorKeyFile = ""
+ DelaySign = "false"
+ OutputType = "WinExe"
+ OutputFileFolder = "\Program Files\NLog.CFTest"
+ RootNamespace = "NLog.CFTest"
+ StartupObject = ""
+ >
+ <Platform Name = "Pocket PC" />
+ <Config
+ Name = "Debug|Pocket PC"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "0"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "DEBUG;TRACE"
+ DocumentationFile = ""
+ DebugSymbols = "true"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ Optimize = "false"
+ OutputPath = "bin\Debug\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ <Config
+ Name = "Release|Pocket PC"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "0"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "TRACE"
+ DocumentationFile = ""
+ DebugSymbols = "false"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ Optimize = "true"
+ OutputPath = "bin\Release\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ </Settings>
+ <References>
+ <Reference
+ Platform = "Pocket PC"
+ Name = "MSCorLib"
+ AssemblyName = "mscorlib"
+ Private = "False"
+ />
+ <Reference
+ Platform = "Pocket PC"
+ Name = "System"
+ AssemblyName = "System"
+ Private = "False"
+ />
+ <Reference
+ Platform = "Pocket PC"
+ Name = "System.Drawing"
+ AssemblyName = "System.Drawing"
+ Private = "False"
+ />
+ <Reference
+ Platform = "Pocket PC"
+ Name = "System.Windows.Forms"
+ AssemblyName = "System.Windows.Forms"
+ Private = "False"
+ />
+ <Reference
+ Platform = "Pocket PC"
+ Name = "System.XML"
+ AssemblyName = "System.Xml"
+ Private = "False"
+ />
+ <Reference
+ Platform = "Pocket PC"
+ Name = "System.Data"
+ AssemblyName = "System.Data"
+ Private = "False"
+ />
+ <Reference
+ Platform = "Pocket PC"
+ Name = "NLog"
+ Project = "{4125C120-539F-4C80-B3D2-35FFF271998A}"
+ Package = "{20D4826A-C6FA-45DB-90F4-C717570B9F32}"
+ />
+ <Reference
+ Platform = "Pocket PC-Designer"
+ Name = "System.CF.Design"
+ AssemblyName = "System.CF.Design"
+ Private = "False"
+ />
+ <Reference
+ Platform = "Pocket PC-Designer"
+ Name = "System.CF.Design.UI"
+ AssemblyName = "System.CF.Design.UI"
+ Private = "False"
+ />
+ <Reference
+ Platform = "Pocket PC-Designer"
+ Name = "System.CF.Windows.Forms"
+ AssemblyName = "System.CF.Windows.Forms"
+ Private = "False"
+ />
+ <Reference
+ Platform = "Pocket PC-Designer"
+ Name = "System.CF.Drawing"
+ AssemblyName = "System.CF.Drawing"
+ Private = "False"
+ />
+ <Reference
+ Platform = "Pocket PC-Designer"
+ Name = "System"
+ AssemblyName = "System"
+ Private = "False"
+ />
+ </References>
+ </Build>
+ <Files>
+ <Include>
+ <File
+ RelPath = "AssemblyInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Form1.cs"
+ SubType = "Form"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Form1.resx"
+ DependentUpon = "Form1.cs"
+ BuildAction = "EmbeddedResource"
+ />
+ <File
+ RelPath = "NLog.CFTest.exe.nlog"
+ BuildAction = "None"
+ />
+ </Include>
+ </Files>
+ </ECSHARP>
+</VisualStudioProject>
+
diff --git a/tests/NLog.CFTest/NLog.CFTest.vs2003.csdproj.user b/tests/NLog.CFTest/NLog.CFTest.vs2003.csdproj.user
new file mode 100644
index 0000000..9c3af9e
--- /dev/null
+++ b/tests/NLog.CFTest/NLog.CFTest.vs2003.csdproj.user
@@ -0,0 +1,55 @@
+<VisualStudioProject>
+ <ECSHARP>
+ <Build>
+ <Settings
+ DeploymentDevice = "Pocket PC Emulator"
+ ReferencePath = ""
+ >
+ <Platform Name = "Pocket PC" />
+ <Config
+ Name = "Debug|Pocket PC"
+ EnableASPDebugging = "false"
+ EnableASPXDebugging = "false"
+ EnableUnmanagedDebugging = "false"
+ EnableSQLServerDebugging = "false"
+ RemoteDebugEnabled = "false"
+ RemoteDebugMachine = ""
+ StartAction = "Project"
+ StartArguments = ""
+ StartPage = ""
+ StartProgram = ""
+ StartURL = ""
+ StartWorkingDirectory = ""
+ StartWithIE = "false"
+ SelectedDevice = "Pocket PC Emulator"
+ DeploymentPlatform = "Pocket PC"
+ />
+ <Config
+ Name = "Release|Pocket PC"
+ EnableASPDebugging = "false"
+ EnableASPXDebugging = "false"
+ EnableUnmanagedDebugging = "false"
+ EnableSQLServerDebugging = "false"
+ RemoteDebugEnabled = "false"
+ RemoteDebugMachine = ""
+ StartAction = "Project"
+ StartArguments = ""
+ StartPage = ""
+ StartProgram = ""
+ StartURL = ""
+ StartWorkingDirectory = ""
+ StartWithIE = "false"
+ SelectedDevice = "Pocket PC Emulator"
+ DeploymentPlatform = "Pocket PC"
+ />
+ </Settings>
+ </Build>
+ <OtherProjectSettings
+ CopyProjectDestinationFolder = ""
+ CopyProjectUncPath = ""
+ CopyProjectOption = "0"
+ ProjectView = "ProjectFiles"
+ />
+ </ECSHARP>
+</VisualStudioProject>
+
diff --git a/tests/NLog.Test/App.config b/tests/NLog.Test/App.config
new file mode 100644
index 0000000..95f792e
--- /dev/null
+++ b/tests/NLog.Test/App.config
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<configuration>
+ <configSections>
+ <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
+ </configSections>
+
+ <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" throwExceptions="true"
+ internalLogFile="NlogErr.txt" internalLogLevel="Trace">
+ <targets>
+ <target xsi:type="Network" name="n" address="udp://localhost:5555" newLine="true" maxMessageSize="60" onOverflow="Error"/>
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="n" />
+ </rules>
+ </nlog>
+</configuration>
+
diff --git a/tests/NLog.Test/Config1.nlog b/tests/NLog.Test/Config1.nlog
new file mode 100644
index 0000000..aa0a859
--- /dev/null
+++ b/tests/NLog.Test/Config1.nlog
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<configuration>
+ <configSections>
+ <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
+ </configSections>
+ <nlog autoReload="true">
+ <appenders>
+ <appender name="console" type="Console" layout="CONFIG1: ${machinename}" />
+ </appenders>
+
+ <rules>
+ <logger name="*" level="Debug" appendTo="console" />
+ </rules>
+ </nlog>
+</configuration>
diff --git a/tests/NLog.Test/Config2.nlog b/tests/NLog.Test/Config2.nlog
new file mode 100644
index 0000000..a90578b
--- /dev/null
+++ b/tests/NLog.Test/Config2.nlog
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<configuration>
+ <configSections>
+ <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
+ </configSections>
+ <nlog autoReload="true">
+ <appenders>
+ <appender name="console" type="Console" layout="CONFIG2: ${machinename}" />
+ </appenders>
+
+ <rules>
+ <logger name="*" appendTo="console" />
+ </rules>
+ </nlog>
+</configuration>
diff --git a/tests/NLog.Test/NLog.Test.vs2003.csproj b/tests/NLog.Test/NLog.Test.vs2003.csproj
new file mode 100644
index 0000000..030c6ed
--- /dev/null
+++ b/tests/NLog.Test/NLog.Test.vs2003.csproj
@@ -0,0 +1,20 @@
+<VisualStudioProject>
+ <CSHARP ProjectType="Local" ProductVersion="7.10.3077" SchemaVersion="2.0" ProjectGuid="{5EC49108-97AE-40EA-B550-8960E4522718}">
+ <Build>
+ <Settings ApplicationIcon="" AssemblyKeyContainerName="" AssemblyName="NLog.Test" AssemblyOriginatorKeyFile="" DefaultClientScript="JScript" DefaultHTMLPageLayout="Grid" DefaultTargetSchema="IE50" DelaySign="false" OutputType="Exe" PreBuildEvent="" PostBuildEvent="" RootNamespace="NLog.Test" RunPostBuildEvent="OnBuildSuccess" StartupObject="">
+ <Config Name="Debug" AllowUnsafeBlocks="false" BaseAddress="285212672" CheckForOverflowUnderflow="false" ConfigurationOverrideFile="" DefineConstants="" DocumentationFile="" DebugSymbols="true" FileAlignment="4096" IncrementalBuild="false" NoStdLib="false" NoWarn="" Optimize="false" OutputPath="bin\Debug\" RegisterForComInterop="false" RemoveIntegerChecks="false" TreatWarningsAsErrors="false" WarningLevel="1" />
+ <Config Name="Release" AllowUnsafeBlocks="false" BaseAddress="285212672" CheckForOverflowUnderflow="false" ConfigurationOverrideFile="" DefineConstants="" DocumentationFile="" DebugSymbols="false" FileAlignment="4096" IncrementalBuild="false" NoStdLib="false" NoWarn="" Optimize="false" OutputPath="bin\Release\" RegisterForComInterop="false" RemoveIntegerChecks="false" TreatWarningsAsErrors="false" WarningLevel="1" />
+ </Settings>
+ <References>
+ <Reference Name="NLog" Project="{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}" Package="{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" />
+ </References>
+ </Build>
+ <Files>
+ <Include>
+ <File RelPath="App.config" BuildAction="None" />
+ <File RelPath="StopWatch.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Test.cs" SubType="Code" BuildAction="Compile" />
+ </Include>
+ </Files>
+ </CSHARP>
+</VisualStudioProject>
\ No newline at end of file
diff --git a/tests/NLog.Test/NLog.Test.vs2005.csproj b/tests/NLog.Test/NLog.Test.vs2005.csproj
new file mode 100644
index 0000000..6c6c003
--- /dev/null
+++ b/tests/NLog.Test/NLog.Test.vs2005.csproj
@@ -0,0 +1,107 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectType>Local</ProjectType>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{5EC49108-97AE-40EA-B550-8960E4522718}</ProjectGuid>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ApplicationIcon>
+ </ApplicationIcon>
+ <AssemblyKeyContainerName>
+ </AssemblyKeyContainerName>
+ <AssemblyName>NLog.Test</AssemblyName>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <DefaultClientScript>JScript</DefaultClientScript>
+ <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+ <DefaultTargetSchema>IE50</DefaultTargetSchema>
+ <DelaySign>false</DelaySign>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>NLog.Test</RootNamespace>
+ <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+ <StartupObject>
+ </StartupObject>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <OutputPath>bin\Debug\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>
+ </DefineConstants>
+ <DocumentationFile>
+ </DocumentationFile>
+ <DebugSymbols>true</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>
+ </NoWarn>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>1</WarningLevel>
+ <DebugType>full</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <OutputPath>bin\Release\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>
+ </DefineConstants>
+ <DocumentationFile>
+ </DocumentationFile>
+ <DebugSymbols>false</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>
+ </NoWarn>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>1</WarningLevel>
+ <DebugType>none</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\NLog\NLog.vs2005.csproj">
+ <Name>NLog.vs2005</Name>
+ <Project>{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}</Project>
+ <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ <Compile Include="StopWatch.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Test.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <ItemGroup />
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>
+ </PreBuildEvent>
+ <PostBuildEvent>
+ </PostBuildEvent>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/tests/NLog.Test/StopWatch.cs b/tests/NLog.Test/StopWatch.cs
new file mode 100644
index 0000000..927124c
--- /dev/null
+++ b/tests/NLog.Test/StopWatch.cs
@@ -0,0 +1,94 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Threading;
+using System.Globalization;
+using System.IO;
+using System.Runtime.InteropServices;
+
+public class StopWatch
+{
+ private long _startTime;
+ private long _stopTime;
+ private static long _overhead = 0;
+ private static long _frequency;
+
+ static StopWatch()
+ {
+ QueryPerformanceFrequency(out _frequency);
+ StopWatch callibration = new StopWatch();
+ long totalOverhead = 0;
+ int loopCount = 0;
+ for (int i = 0; i < 10000; ++i)
+ {
+ callibration.Start();
+ callibration.Stop();
+ totalOverhead += callibration.Ticks;
+ loopCount++;
+ }
+ _overhead = totalOverhead / loopCount;
+ //Console.WriteLine("Callibrating StopWatch: overhead {0}", _overhead);
+ }
+
+ public void Start()
+ {
+ QueryPerformanceCounter(out _startTime);
+ }
+
+ public void Stop()
+ {
+ QueryPerformanceCounter(out _stopTime);
+ }
+
+ public long Ticks
+ {
+ get { return _stopTime - _startTime - _overhead; }
+ }
+
+ public double Seconds
+ {
+ get { return (double)(_stopTime - _startTime - _overhead) / _frequency; }
+ }
+
+ public double Nanoseconds
+ {
+ get { return (double)1000000000 * (_stopTime - _startTime - _overhead) / _frequency; }
+ }
+
+ [DllImport("kernel32.dll")]
+ static extern bool QueryPerformanceCounter(out long val);
+
+ [DllImport("kernel32.dll")]
+ static extern bool QueryPerformanceFrequency(out long val);
+}
diff --git a/tests/NLog.Test/Test.cs b/tests/NLog.Test/Test.cs
new file mode 100644
index 0000000..a402781
--- /dev/null
+++ b/tests/NLog.Test/Test.cs
@@ -0,0 +1,90 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+using NLog;
+using NLog.Config;
+using NLog.Targets.Compound;
+using NLog.Targets.Wrappers;
+using NLog.Conditions;
+using NLog.Targets;
+using NLog.Win32.Targets;
+using NLog.Internal;
+using System.IO;
+using System.Threading;
+
+namespace NLog.Tester
+{
+ public class Test
+ {
+ private static Logger logger = LogManager.GetCurrentClassLogger();
+
+ public static void LogProc(string msg)
+ {
+ Console.WriteLine("logproc: {0}", msg);
+ }
+
+ static void A()
+ {
+ B(3);
+ }
+
+ static void B(int a)
+ {
+ logger.Trace("ttt");
+ logger.Debug("ala ma kota");
+ logger.Info("ala ma kanarka");
+ logger.Warn("aaa");
+ logger.Error("err");
+ logger.Fatal("fff");
+ }
+
+ static void Main(string[]args)
+ {
+ //InternalLogger.LogToConsole = true;
+ //InternalLogger.LogLevel = LogLevel.Debug;
+
+ for (int i = 0; i < 3; ++i)
+ {
+ logger.Trace("ttt");
+ logger.Debug("ala ma kota {0}", i);
+ logger.Info("ala ma kanarka");
+ logger.Warn("aaa");
+ logger.Error("err");
+ logger.Fatal("fff");
+ }
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests.Web/ASPNetTests.cs b/tests/NLog.UnitTests.Web/ASPNetTests.cs
new file mode 100644
index 0000000..7b2f647
--- /dev/null
+++ b/tests/NLog.UnitTests.Web/ASPNetTests.cs
@@ -0,0 +1,107 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+using System.IO;
+using System.Net;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.Web
+{
+ [TestFixture]
+ public class ASPNetTests : NLogWebTestBase
+ {
+ [Test]
+ public void GetTest()
+ {
+ ClearASPNetTrace();
+ string got = DownloadUrl("test.aspx");
+ Assert.AreEqual("loaded!", got);
+ string trace = GetFirstASPNetTrace();
+ AssertContains(trace, "Global.Logger");
+
+ AssertContains(trace, "Info Application_BeginRequest");
+ AssertContains(trace, "Info Application_AuthenticateRequest");
+ AssertContains(trace, "Info Application_AuthorizeRequest");
+ AssertContains(trace, "Info Session_Start");
+ AssertContains(trace, "Info Application_PreRequestHandlerExecute");
+ AssertContains(trace, "test.aspx");
+ AssertContains(trace, "Info got Page_Load() event");
+ AssertContains(trace, "Warn Some warning");
+ AssertContains(trace, "Error Some error");
+ //Console.WriteLine("got: {0}", trace);
+ }
+
+ [Test]
+ public void ContextTest()
+ {
+ //
+ // simulate a POST request, with "formvariable=fv1" POST data,
+ // cookie1=abcd Cookie and ?queryparam=1234 query string
+ //
+ // expect the web server to return a formatted text that
+ // uses all layout renderers
+ //
+
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(NLogTestBaseUrl + "context.aspx?queryparam=1234");
+ request.Headers.Add("Cookie: cookie1=abcd");
+ request.Method = "POST";
+ request.ContentType = "application/x-www-form-urlencoded";
+
+ string postDataString = "formvariable=fv1";
+ byte[] postData = System.Text.Encoding.ASCII.GetBytes(postDataString);
+ request.ContentLength = postData.Length;
+ using (Stream requestStream = request.GetRequestStream())
+ {
+ requestStream.Write(postData, 0, postData.Length);
+ }
+ using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
+ {
+ Console.WriteLine(response.ContentLength);
+ Console.WriteLine(response.ContentType);
+ byte[] data = new byte[4000];
+ int got;
+
+ using (Stream stream = response.GetResponseStream())
+ {
+ got = stream.Read(data, 0, data.Length);
+ }
+ string s = System.Text.Encoding.ASCII.GetString(data, 0, got);
+ Assert.AreEqual("id='1234', form='fv1', cookie='abcd', servervariable='/nlogtest/context.aspx' item='1234' session='sessionvalue1' app='appvalue1' message", s);
+ }
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests.Web/ASPTests.cs b/tests/NLog.UnitTests.Web/ASPTests.cs
new file mode 100644
index 0000000..11566db
--- /dev/null
+++ b/tests/NLog.UnitTests.Web/ASPTests.cs
@@ -0,0 +1,86 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+using System.IO;
+using System.Net;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.Web
+{
+ [TestFixture]
+ public class ASPTests : NLogWebTestBase
+ {
+ [Test]
+ public void ContextTest()
+ {
+ //
+ // simulate a POST request, with "formvariable=fv1" POST data,
+ // cookie1=abcd Cookie and ?queryparam=1234 query string
+ //
+ // expect the web server to return a formatted text that
+ // uses all layout renderers
+ //
+
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(NLogTestBaseUrl + "context.asp?queryparam=1234");
+ request.Headers.Add("Cookie: cookie1=abcd");
+ request.Method = "POST";
+ request.ContentType = "application/x-www-form-urlencoded";
+
+ string postDataString = "formvariable=fv1";
+ byte[] postData = System.Text.Encoding.ASCII.GetBytes(postDataString);
+ request.ContentLength = postData.Length;
+ using (Stream requestStream = request.GetRequestStream())
+ {
+ requestStream.Write(postData, 0, postData.Length);
+ }
+ using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
+ {
+ Console.WriteLine(response.ContentLength);
+ Console.WriteLine(response.ContentType);
+ byte[] data = new byte[4000];
+ int got;
+
+ using (Stream stream = response.GetResponseStream())
+ {
+ got = stream.Read(data, 0, data.Length);
+ }
+ string s = System.Text.Encoding.ASCII.GetString(data, 0, got);
+ Assert.AreEqual("id='1234', form='fv1', cookie='abcd', servervariable='/nlogtest/context.asp' item='1234' session='sessionvalue2' app='appvalue2' message", s);
+ }
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests.Web/AssemblyInfo.cs b/tests/NLog.UnitTests.Web/AssemblyInfo.cs
new file mode 100644
index 0000000..afcfb1c
--- /dev/null
+++ b/tests/NLog.UnitTests.Web/AssemblyInfo.cs
@@ -0,0 +1,91 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.0.0")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+// (*) If no key is specified, the assembly is not signed.
+// (*) KeyName refers to a key that has been installed in the Crypto Service
+// Provider (CSP) on your machine. KeyFile refers to a file which contains
+// a key.
+// (*) If the KeyFile and the KeyName values are both specified, the
+// following processing occurs:
+// (1) If the KeyName can be found in the CSP, that key is used.
+// (2) If the KeyName does not exist and the KeyFile does exist, the key
+// in the KeyFile is installed into the CSP and used.
+// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+// When specifying the KeyFile, the location of the KeyFile should be
+// relative to the project output directory which is
+// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
+// located in the project directory, you would specify the AssemblyKeyFile
+// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+// documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]
diff --git a/tests/NLog.UnitTests.Web/NLog.UnitTests.Web.csproj b/tests/NLog.UnitTests.Web/NLog.UnitTests.Web.csproj
new file mode 100644
index 0000000..79f63c7
--- /dev/null
+++ b/tests/NLog.UnitTests.Web/NLog.UnitTests.Web.csproj
@@ -0,0 +1,116 @@
+<VisualStudioProject>
+ <CSHARP
+ ProjectType = "Local"
+ ProductVersion = "7.10.3077"
+ SchemaVersion = "2.0"
+ ProjectGuid = "{8812AE40-15E0-4A88-8FDB-453D9D7A5EFD}"
+ >
+ <Build>
+ <Settings
+ ApplicationIcon = ""
+ AssemblyKeyContainerName = ""
+ AssemblyName = "NLog.UnitTests.Web"
+ AssemblyOriginatorKeyFile = ""
+ DefaultClientScript = "JScript"
+ DefaultHTMLPageLayout = "Grid"
+ DefaultTargetSchema = "IE50"
+ DelaySign = "false"
+ OutputType = "Library"
+ PreBuildEvent = ""
+ PostBuildEvent = ""
+ RootNamespace = "NLog.UnitTests.Web"
+ RunPostBuildEvent = "OnBuildSuccess"
+ StartupObject = ""
+ >
+ <Config
+ Name = "Debug"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "DEBUG;TRACE"
+ DocumentationFile = ""
+ DebugSymbols = "true"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = ""
+ Optimize = "false"
+ OutputPath = "bin\Debug\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ <Config
+ Name = "Release"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "TRACE"
+ DocumentationFile = ""
+ DebugSymbols = "false"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = ""
+ Optimize = "true"
+ OutputPath = "bin\Release\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ </Settings>
+ <References>
+ <Reference
+ Name = "System"
+ AssemblyName = "System"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll"
+ />
+ <Reference
+ Name = "System.Data"
+ AssemblyName = "System.Data"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
+ />
+ <Reference
+ Name = "System.XML"
+ AssemblyName = "System.XML"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
+ />
+ <Reference
+ Name = "nunit.framework"
+ AssemblyName = "nunit.framework"
+ HintPath = "C:\Program Files\NUnit 2.2\bin\nunit.framework.dll"
+ AssemblyFolderKey = "hklm\dn\nunit.framework"
+ />
+ </References>
+ </Build>
+ <Files>
+ <Include>
+ <File
+ RelPath = "ASPNetTests.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "ASPTests.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "AssemblyInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "NLogWebTestBase.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ </Include>
+ </Files>
+ </CSHARP>
+</VisualStudioProject>
+
diff --git a/tests/NLog.UnitTests.Web/NLogWebTestBase.cs b/tests/NLog.UnitTests.Web/NLogWebTestBase.cs
new file mode 100644
index 0000000..4b17500
--- /dev/null
+++ b/tests/NLog.UnitTests.Web/NLogWebTestBase.cs
@@ -0,0 +1,70 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Net;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.Web
+{
+ public class NLogWebTestBase
+ {
+ public string WebTestDir;
+ public string NLogTestBaseUrl = "http://localhost/nlogtest/";
+
+ protected void ClearASPNetTrace()
+ {
+ DownloadUrl("Trace.axd?clear=1");
+ }
+
+ protected string GetFirstASPNetTrace()
+ {
+ return DownloadUrl("Trace.axd?id=0");
+ }
+
+ protected string DownloadUrl(string url)
+ {
+ WebClient wc = new WebClient();
+ byte[] data = wc.DownloadData(NLogTestBaseUrl + url);
+ return System.Text.Encoding.ASCII.GetString(data);
+ }
+
+ protected void AssertContains(string trace, string substr)
+ {
+ Assert.IsTrue(trace.IndexOf(substr) >= 0, "Trace doesn't contain a '" + substr + "' text.");
+ Console.WriteLine("Trace contains '{0}' text.", substr);
+
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/AssemblyInfo.cs b/tests/NLog.UnitTests/AssemblyInfo.cs
new file mode 100644
index 0000000..afcfb1c
--- /dev/null
+++ b/tests/NLog.UnitTests/AssemblyInfo.cs
@@ -0,0 +1,91 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.0.0")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+// (*) If no key is specified, the assembly is not signed.
+// (*) KeyName refers to a key that has been installed in the Crypto Service
+// Provider (CSP) on your machine. KeyFile refers to a file which contains
+// a key.
+// (*) If the KeyFile and the KeyName values are both specified, the
+// following processing occurs:
+// (1) If the KeyName can be found in the CSP, that key is used.
+// (2) If the KeyName does not exist and the KeyFile does exist, the key
+// in the KeyFile is installed into the CSP and used.
+// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+// When specifying the KeyFile, the location of the KeyFile should be
+// relative to the project output directory which is
+// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
+// located in the project directory, you would specify the AssemblyKeyFile
+// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+// documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]
diff --git a/tests/NLog.UnitTests/CaseSensitivityTests.cs b/tests/NLog.UnitTests/CaseSensitivityTests.cs
new file mode 100644
index 0000000..1653b59
--- /dev/null
+++ b/tests/NLog.UnitTests/CaseSensitivityTests.cs
@@ -0,0 +1,127 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests
+{
+ [TestFixture]
+ public class CaseSensitivityTests : NLogTestBase
+ {
+ [Test]
+ public void UpperCaseTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='info' appendto='debug'>
+ <filters>
+ <whencontains layout='${message}' substring='msg' action='ignore' />
+ </filters>
+ </logger>
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("msg");
+ logger.Info("msg");
+ logger.Warn("msg");
+ logger.Error("msg");
+ logger.Fatal("msg");
+ logger.Debug("message");
+ AssertDebugCounter("debug", 0);
+
+ logger.Info("message");
+ AssertDebugCounter("debug", 1);
+
+ logger.Warn("message");
+ AssertDebugCounter("debug", 2);
+
+ logger.Error("message");
+ AssertDebugCounter("debug", 3);
+
+ logger.Fatal("message");
+ AssertDebugCounter("debug", 4);
+ }
+
+ [Test]
+ public void LowerCaseTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <TARGETS><TARGET NAME='DEBUG' TYPE='DEBUG' LAYOUT='${MESSAGE}' /></TARGETS>
+ <RULES>
+ <LOGGER NAME='*' MINLEVEL='INFO' APPENDTO='DEBUG'>
+ <FILTERS>
+ <WHENCONTAINS LAYOUT='${MESSAGE}' SUBSTRING='msg' ACTION='IGNORE' />
+ </FILTERS>
+ </LOGGER>
+ </RULES>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("msg");
+ logger.Info("msg");
+ logger.Warn("msg");
+ logger.Error("msg");
+ logger.Fatal("msg");
+ logger.Debug("message");
+ AssertDebugCounter("debug", 0);
+
+ logger.Info("message");
+ AssertDebugCounter("debug", 1);
+
+ logger.Warn("message");
+ AssertDebugCounter("debug", 2);
+
+ logger.Error("message");
+ AssertDebugCounter("debug", 3);
+
+ logger.Fatal("message");
+ AssertDebugCounter("debug", 4);
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/Filters/APITests.cs b/tests/NLog.UnitTests/Filters/APITests.cs
new file mode 100644
index 0000000..7dcff5b
--- /dev/null
+++ b/tests/NLog.UnitTests/Filters/APITests.cs
@@ -0,0 +1,75 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+using System.IO;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.Filters
+{
+ [TestFixture]
+ public class APITests : NLogTestBase
+ {
+ [Test]
+ public void APITest()
+ {
+ // this is mostly to make Clover happy
+
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${basedir} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug'>
+ <filters>
+ <whenContains layout='${message}' substring='zzz' action='Ignore' />
+ </filters>
+ </logger>
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+ Assert.IsTrue(LogManager.Configuration.LoggingRules[0].Filters[0] is NLog.Filters.WhenContainsFilter);
+ NLog.Filters.WhenContainsFilter wcf = (NLog.Filters.WhenContainsFilter)LogManager.Configuration.LoggingRules[0].Filters[0];
+ Assert.AreEqual(wcf.Layout, "${message}");
+ Assert.AreEqual(wcf.Substring, "zzz");
+ Assert.AreEqual(FilterResult.Ignore, wcf.Action);
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/Filters/WhenContainsTests.cs b/tests/NLog.UnitTests/Filters/WhenContainsTests.cs
new file mode 100644
index 0000000..f9cc72a
--- /dev/null
+++ b/tests/NLog.UnitTests/Filters/WhenContainsTests.cs
@@ -0,0 +1,105 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+using System.IO;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.Filters
+{
+ [TestFixture]
+ public class WhenContainsTests : NLogTestBase
+ {
+ [Test]
+ public void WhenContainsTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${basedir} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug'>
+ <filters>
+ <whenContains layout='${message}' substring='zzz' action='Ignore' />
+ </filters>
+ </logger>
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugCounter("debug", 1);
+ logger.Debug("zzz");
+ AssertDebugCounter("debug", 1);
+ logger.Debug("ZzzZ");
+ AssertDebugCounter("debug", 2);
+ }
+
+ [Test]
+ public void WhenContainsInsensitiveTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${basedir} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug'>
+ <filters>
+ <whenContains layout='${message}' substring='zzz' action='Ignore' ignoreCase='true' />
+ </filters>
+ </logger>
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugCounter("debug", 1);
+ logger.Debug("zzz");
+ AssertDebugCounter("debug", 1);
+ logger.Debug("ZzzZ");
+ AssertDebugCounter("debug", 1);
+ logger.Debug("aaa");
+ AssertDebugCounter("debug", 2);
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/Filters/WhenEqualTests.cs b/tests/NLog.UnitTests/Filters/WhenEqualTests.cs
new file mode 100644
index 0000000..7b2607b
--- /dev/null
+++ b/tests/NLog.UnitTests/Filters/WhenEqualTests.cs
@@ -0,0 +1,103 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+using System.IO;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.Filters
+{
+ [TestFixture]
+ public class WhenEqualTests : NLogTestBase
+ {
+ [Test]
+ public void WhenEqualTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${basedir} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug'>
+ <filters>
+ <whenEqual layout='${message}' compareTo='skipme' action='Ignore' />
+ </filters>
+ </logger>
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugCounter("debug", 1);
+ logger.Debug("skipme");
+ AssertDebugCounter("debug", 1);
+ logger.Debug("SkipMe");
+ AssertDebugCounter("debug", 2);
+ }
+
+ [Test]
+ public void WhenEqualInsensitiveTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${basedir} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug'>
+ <filters>
+ <whenEqual layout='${message}' compareTo='skipmetoo' action='Ignore' ignoreCase='true' />
+ </filters>
+ </logger>
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugCounter("debug", 1);
+ logger.Debug("skipMeToo");
+ AssertDebugCounter("debug", 1);
+ logger.Debug("skipmetoo");
+ AssertDebugCounter("debug", 1);
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/Filters/WhenNotContainsTests.cs b/tests/NLog.UnitTests/Filters/WhenNotContainsTests.cs
new file mode 100644
index 0000000..3cc554d
--- /dev/null
+++ b/tests/NLog.UnitTests/Filters/WhenNotContainsTests.cs
@@ -0,0 +1,105 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+using System.IO;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.Filters
+{
+ [TestFixture]
+ public class WhenNotContainsTests : NLogTestBase
+ {
+ [Test]
+ public void WhenNotContainsTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${basedir} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug'>
+ <filters>
+ <whenNotContains layout='${message}' substring='zzz' action='Ignore' />
+ </filters>
+ </logger>
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugCounter("debug", 0);
+ logger.Debug("zzz");
+ AssertDebugCounter("debug", 1);
+ logger.Debug("ZzzZ");
+ AssertDebugCounter("debug", 1);
+ }
+
+ [Test]
+ public void WhenNotContainsInsensitiveTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${basedir} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug'>
+ <filters>
+ <whenNotContains layout='${message}' substring='zzz' action='Ignore' ignoreCase='true' />
+ </filters>
+ </logger>
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugCounter("debug", 0);
+ logger.Debug("zzz");
+ AssertDebugCounter("debug", 1);
+ logger.Debug("ZzzZ");
+ AssertDebugCounter("debug", 2);
+ logger.Debug("aaa");
+ AssertDebugCounter("debug", 2);
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/Filters/WhenNotEqualTests.cs b/tests/NLog.UnitTests/Filters/WhenNotEqualTests.cs
new file mode 100644
index 0000000..893744d
--- /dev/null
+++ b/tests/NLog.UnitTests/Filters/WhenNotEqualTests.cs
@@ -0,0 +1,105 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+using System.IO;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.Filters
+{
+ [TestFixture]
+ public class WhenNotEqualTests : NLogTestBase
+ {
+ [Test]
+ public void WhenNotEqualTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${basedir} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug'>
+ <filters>
+ <whenNotEqual layout='${message}' compareTo='skipme' action='Ignore' />
+ </filters>
+ </logger>
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugCounter("debug", 0);
+ logger.Debug("skipme");
+ AssertDebugCounter("debug", 1);
+ logger.Debug("SkipMe");
+ AssertDebugCounter("debug", 1);
+ }
+
+ [Test]
+ public void WhenNotEqualInsensitiveTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${basedir} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug'>
+ <filters>
+ <whenNotEqual layout='${message}' compareTo='skipmetoo' action='Ignore' ignoreCase='true' />
+ </filters>
+ </logger>
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugCounter("debug", 0);
+ logger.Debug("skipMeToo");
+ AssertDebugCounter("debug", 1);
+ logger.Debug("skipmetoo");
+ AssertDebugCounter("debug", 2);
+ logger.Debug("dontskipme");
+ AssertDebugCounter("debug", 2);
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/GetLoggerTests.cs b/tests/NLog.UnitTests/GetLoggerTests.cs
new file mode 100644
index 0000000..87f8672
--- /dev/null
+++ b/tests/NLog.UnitTests/GetLoggerTests.cs
@@ -0,0 +1,147 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests
+{
+ [TestFixture]
+ public class GetLoggerTests : NLogTestBase
+ {
+ [Test]
+ public void GetCurrentClassLoggerTest()
+ {
+ Logger logger = LogManager.GetCurrentClassLogger();
+
+ Assert.AreEqual("NLog.UnitTests.GetLoggerTests", logger.Name);
+ }
+
+ [Test]
+ public void TypedGetLoggerTest()
+ {
+ LogFactory lf = new LogFactory();
+
+ MyLogger l1 = (MyLogger)lf.GetLogger("AAA", typeof(MyLogger));
+ MyLogger l2 = (MyLogger)lf.GetLogger("AAA", typeof(MyLogger));
+ Logger l3 = lf.GetLogger("AAA", typeof(Logger));
+ Logger l4 = lf.GetLogger("AAA", typeof(Logger));
+ Logger l5 = lf.GetLogger("AAA");
+ Logger l6 = lf.GetLogger("AAA");
+
+ Assert.AreSame(l1, l2);
+ Assert.AreSame(l3, l4);
+ Assert.AreSame(l5, l6);
+ Assert.AreSame(l3, l5);
+
+ Assert.AreNotSame(l1, l3);
+
+ Assert.AreEqual("AAA", l1.Name);
+ Assert.AreEqual("AAA", l3.Name);
+ }
+
+ [Test]
+ public void TypedGetCurrentClassLoggerTest()
+ {
+ LogFactory lf = new LogFactory();
+
+ MyLogger l1 = (MyLogger)lf.GetCurrentClassLogger(typeof(MyLogger));
+ MyLogger l2 = (MyLogger)lf.GetCurrentClassLogger(typeof(MyLogger));
+ Logger l3 = lf.GetCurrentClassLogger(typeof(Logger));
+ Logger l4 = lf.GetCurrentClassLogger(typeof(Logger));
+ Logger l5 = lf.GetCurrentClassLogger();
+ Logger l6 = lf.GetCurrentClassLogger();
+
+ Assert.AreSame(l1, l2);
+ Assert.AreSame(l3, l4);
+ Assert.AreSame(l5, l6);
+ Assert.AreSame(l3, l5);
+
+ Assert.AreNotSame(l1, l3);
+
+ Assert.AreEqual("NLog.UnitTests.GetLoggerTests", l1.Name);
+ Assert.AreEqual("NLog.UnitTests.GetLoggerTests", l3.Name);
+ }
+
+
+#if A
+ [Test]
+ public void GenericGetLoggerTest()
+ {
+ LogFactory<MyLogger> lf = new LogFactory<MyLogger>();
+
+ MyLogger l1 = lf.GetLogger("AAA");
+ MyLogger l2 = lf.GetLogger("AAA");
+ MyLogger l3 = lf.GetLogger("BBB");
+
+ Assert.AreSame(l1, l2);
+ Assert.AreNotSame(l1, l3);
+
+ Assert.AreEqual("AAA", l1.Name);
+ Assert.AreEqual("BBB", l3.Name);
+ }
+
+ [Test]
+ public void GenericGetCurrentClassLoggerTest()
+ {
+ LogFactory<MyLogger> lf = new LogFactory<MyLogger>();
+
+ MyLogger l1 = lf.GetCurrentClassLogger();
+ MyLogger l2 = lf.GetCurrentClassLogger();
+
+ Assert.AreSame(l1, l2);
+ Assert.AreEqual("NLog.UnitTests.GetLoggerTests", l1.Name);
+ }
+
+#endif
+
+ public class MyLogger : Logger
+ {
+ public MyLogger()
+ {
+ }
+
+ public void LogWithEventID(int eventID, string message, object[] par)
+ {
+ LogEventInfo lei = new LogEventInfo(LogLevel.Info, this.Name, null, message, par);
+ lei.Context["EventID"] = eventID;
+ base.Log(typeof(MyLogger), lei);
+ }
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutConfigurationTests.cs b/tests/NLog.UnitTests/LayoutConfigurationTests.cs
new file mode 100644
index 0000000..5d14941
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutConfigurationTests.cs
@@ -0,0 +1,194 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Globalization;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+using NLog.LayoutRenderers;
+
+namespace NLog.UnitTests
+{
+ [TestFixture]
+ public class LayoutConfigurationTests : NLogTestBase
+ {
+ [Test]
+ public void SimpleTest()
+ {
+ Layout l = new Layout("${message}");
+ Assert.AreEqual(1, l.Renderers.Length);
+ Assert.IsInstanceOfType(typeof(NLog.LayoutRenderers.MessageLayoutRenderer), l.Renderers[0]);
+ }
+
+ [Test]
+ public void UnclosedTest()
+ {
+ Layout l = new Layout("${message");
+ }
+
+ [Test]
+ public void SingleParamTest()
+ {
+ Layout l = new Layout("${mdc:item=AAA}");
+ Assert.AreEqual(1, l.Renderers.Length);
+ MDCLayoutRenderer mdc = l.Renderers[0] as MDCLayoutRenderer;
+ Assert.IsNotNull(mdc);
+ Assert.AreEqual("AAA", mdc.Item);
+ }
+
+ [Test]
+ public void ValueWithColonTest()
+ {
+ Layout l = new Layout("${mdc:item=AAA\\:}");
+ Assert.AreEqual(1, l.Renderers.Length);
+ MDCLayoutRenderer mdc = l.Renderers[0] as MDCLayoutRenderer;
+ Assert.IsNotNull(mdc);
+ Assert.AreEqual("AAA:", mdc.Item);
+ }
+
+ [Test]
+ public void ValueWithBracketTest()
+ {
+ Layout l = new Layout("${mdc:item=AAA\\}\\:}");
+ Assert.AreEqual("${mdc:item=AAA\\}\\:}", l.Text);
+ Assert.AreEqual(1, l.Renderers.Length);
+ MDCLayoutRenderer mdc = l.Renderers[0] as MDCLayoutRenderer;
+ Assert.IsNotNull(mdc);
+ Assert.AreEqual("AAA}:", mdc.Item);
+ }
+
+ [Test]
+ public void DefaultValueTest()
+ {
+ Layout l = new Layout("${mdc:BBB}");
+ Assert.AreEqual(1, l.Renderers.Length);
+ MDCLayoutRenderer mdc = l.Renderers[0] as MDCLayoutRenderer;
+ Assert.IsNotNull(mdc);
+ Assert.AreEqual("BBB", mdc.Item);
+ }
+
+ [Test]
+ public void DefaultValueWithBracketTest()
+ {
+ Layout l = new Layout("${mdc:AAA\\}\\:}");
+ Assert.AreEqual(l.Text,"${mdc:AAA\\}\\:}");
+ Assert.AreEqual(1, l.Renderers.Length);
+ MDCLayoutRenderer mdc = l.Renderers[0] as MDCLayoutRenderer;
+ Assert.IsNotNull(mdc);
+ Assert.AreEqual("AAA}:", mdc.Item);
+ }
+
+ [Test]
+ public void DefaultValueWithOtherParametersTest()
+ {
+ Layout l = new Layout("${mdc:BBB:padding=3:padcharacter=X}");
+ Assert.AreEqual(1, l.Renderers.Length);
+ MDCLayoutRenderer mdc = l.Renderers[0] as MDCLayoutRenderer;
+ Assert.IsNotNull(mdc);
+ Assert.AreEqual("BBB", mdc.Item);
+ Assert.AreEqual(3, mdc.Padding);
+ Assert.AreEqual('X', mdc.PadCharacter);
+ }
+
+ [Test]
+ public void EmptyValueTest()
+ {
+ Layout l = new Layout("${mdc:item=}");
+ Assert.AreEqual(1, l.Renderers.Length);
+ MDCLayoutRenderer mdc = l.Renderers[0] as MDCLayoutRenderer;
+ Assert.IsNotNull(mdc);
+ Assert.AreEqual("", mdc.Item);
+ }
+
+ [Test]
+ public void NestedLayoutTest()
+ {
+ Layout l = new Layout("${file-contents:fileName=${basedir:padding=10}/aaa.txt:padding=12}");
+ Assert.AreEqual(1, l.Renderers.Length);
+ FileContentsLayoutRenderer lr = l.Renderers[0] as FileContentsLayoutRenderer;
+ Assert.IsNotNull(lr);
+ Assert.IsInstanceOfType(typeof(Layout), lr.FileName);
+ Assert.AreEqual("${basedir:padding=10}/aaa.txt", lr.FileName.Text);
+ Assert.AreEqual(1, lr.FileName.Renderers.Length);
+ Assert.AreEqual(12, lr.Padding);
+ }
+
+ [Test]
+ public void DoubleNestedLayoutTest()
+ {
+ Layout l = new Layout("${file-contents:fileName=${basedir}/${file-contents:fileName=${basedir}/aaa.txt}/aaa.txt}");
+ Assert.AreEqual(1, l.Renderers.Length);
+ FileContentsLayoutRenderer lr = l.Renderers[0] as FileContentsLayoutRenderer;
+ Assert.IsNotNull(lr);
+ Assert.IsInstanceOfType(typeof(Layout), lr.FileName);
+ Assert.AreEqual("${basedir}/${file-contents:fileName=${basedir}/aaa.txt}/aaa.txt", lr.FileName.Text);
+ Assert.AreEqual(3, lr.FileName.Renderers.Length);
+ Assert.IsInstanceOfType(typeof(LiteralLayoutRenderer), lr.FileName.Renderers[0]);
+ Assert.IsInstanceOfType(typeof(FileContentsLayoutRenderer), lr.FileName.Renderers[1]);
+ Assert.IsInstanceOfType(typeof(LiteralLayoutRenderer), lr.FileName.Renderers[2]);
+
+ LiteralLayoutRenderer lr1 = (LiteralLayoutRenderer)lr.FileName.Renderers[0];
+ FileContentsLayoutRenderer fc = (FileContentsLayoutRenderer)lr.FileName.Renderers[1];
+ LiteralLayoutRenderer lr2 = (LiteralLayoutRenderer)lr.FileName.Renderers[2];
+
+ Assert.AreEqual("${basedir}/aaa.txt", fc.FileName.Text);
+
+ }
+
+ [Test]
+ public void DoubleNestedLayoutWithDefaultLayoutParametersTest()
+ {
+ Layout l = new Layout("${file-contents:${basedir}/${file-contents:${basedir}/aaa.txt}/aaa.txt}");
+ Assert.AreEqual(1, l.Renderers.Length);
+ FileContentsLayoutRenderer lr = l.Renderers[0] as FileContentsLayoutRenderer;
+ Assert.IsNotNull(lr);
+ Assert.IsInstanceOfType(typeof(Layout), lr.FileName);
+ Assert.AreEqual("${basedir}/${file-contents:${basedir}/aaa.txt}/aaa.txt", lr.FileName.Text);
+ Assert.AreEqual(3, lr.FileName.Renderers.Length);
+ Assert.IsInstanceOfType(typeof(LiteralLayoutRenderer), lr.FileName.Renderers[0]);
+ Assert.IsInstanceOfType(typeof(FileContentsLayoutRenderer), lr.FileName.Renderers[1]);
+ Assert.IsInstanceOfType(typeof(LiteralLayoutRenderer), lr.FileName.Renderers[2]);
+
+ LiteralLayoutRenderer lr1 = (LiteralLayoutRenderer)lr.FileName.Renderers[0];
+ FileContentsLayoutRenderer fc = (FileContentsLayoutRenderer)lr.FileName.Renderers[1];
+ LiteralLayoutRenderer lr2 = (LiteralLayoutRenderer)lr.FileName.Renderers[2];
+
+ Assert.AreEqual("${basedir}/aaa.txt", fc.FileName.Text);
+
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/BaseDirTests.cs b/tests/NLog.UnitTests/LayoutRenderers/BaseDirTests.cs
new file mode 100644
index 0000000..a296044
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/BaseDirTests.cs
@@ -0,0 +1,72 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+using System.IO;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class BaseDirTests : NLogTestBase
+ {
+ private string baseDir = AppDomain.CurrentDomain.BaseDirectory;
+
+ [Test]
+ public void BaseDirTest()
+ {
+ Layout l = new Layout("${basedir}");
+ AssertLayoutRendererOutput(l, baseDir);
+ }
+
+ [Test]
+ public void BaseDirCombineTest()
+ {
+ Layout l = new Layout("${basedir:dir=aaa}");
+ AssertLayoutRendererOutput(l, Path.Combine(baseDir,"aaa"));
+ }
+
+ [Test]
+ public void BaseDirFileCombineTest()
+ {
+ Layout l = new Layout("${basedir:file=aaa.txt}");
+ AssertLayoutRendererOutput(l, Path.Combine(baseDir, "aaa.txt"));
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/CallSiteTests.cs b/tests/NLog.UnitTests/LayoutRenderers/CallSiteTests.cs
new file mode 100644
index 0000000..df7ac13
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/CallSiteTests.cs
@@ -0,0 +1,153 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+using System.Diagnostics;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class CallSiteTests : NLogTestBase
+ {
+ [Test]
+ public void LineNumberTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${callsite:filename=true} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+#line 100000
+ logger.Debug("msg");
+ string lastMessage = GetDebugLastMessage("debug");
+ // There's a difference in handling line numbers between .NET and Mono
+ // We're just interested in checking if it's above 100000
+ Assert.IsTrue(lastMessage.ToLower().IndexOf("callsitetests.cs:10000") >= 0, "Invalid line number. Expected prefix of 10000, got: " + lastMessage);
+#line default
+ }
+
+ [Test]
+ public void MethodNameTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${callsite} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("msg");
+ MethodBase currentMethod = MethodBase.GetCurrentMethod();
+ AssertDebugLastMessage("debug", currentMethod.DeclaringType.FullName + "." + currentMethod.Name + " msg");
+ }
+
+ [Test]
+ public void ClassNameTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${callsite:classname=true:methodname=false} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("msg");
+ MethodBase currentMethod = MethodBase.GetCurrentMethod();
+ AssertDebugLastMessage("debug", currentMethod.DeclaringType.FullName + " msg");
+ }
+
+ [Test]
+ public void ClassNameWithPaddingTestTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${callsite:classname=true:methodname=false:padding=3:fixedlength=true} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("msg");
+ MethodBase currentMethod = MethodBase.GetCurrentMethod();
+ AssertDebugLastMessage("debug", currentMethod.DeclaringType.FullName.Substring(0,3) + " msg");
+ }
+
+ [Test]
+ public void MethodNameWithPaddingTestTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${callsite:classname=false:methodname=true:padding=16:fixedlength=true} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("msg");
+ MethodBase currentMethod = MethodBase.GetCurrentMethod();
+ AssertDebugLastMessage("debug", "MethodNameWithPa msg");
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/CounterTests.cs b/tests/NLog.UnitTests/LayoutRenderers/CounterTests.cs
new file mode 100644
index 0000000..ef11212
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/CounterTests.cs
@@ -0,0 +1,128 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class CounterTests : NLogTestBase
+ {
+ [Test]
+ public void DefaultCounterTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message} ${counter} ${counter}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Info' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ logger.Info("a");
+ AssertDebugLastMessage("debug", "a 1 1");
+ logger.Warn("a");
+ AssertDebugLastMessage("debug", "a 2 2");
+ logger.Error("a");
+ AssertDebugLastMessage("debug", "a 3 3");
+ logger.Fatal("a");
+ AssertDebugLastMessage("debug", "a 4 4");
+ }
+
+ [Test]
+ public void PresetCounterTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message} ${counter:value=1:increment=3} ${counter}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Info' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ logger.Info("a");
+ AssertDebugLastMessage("debug", "a 1 1");
+ logger.Warn("a");
+ AssertDebugLastMessage("debug", "a 4 2");
+ logger.Error("a");
+ AssertDebugLastMessage("debug", "a 7 3");
+ logger.Fatal("a");
+ AssertDebugLastMessage("debug", "a 10 4");
+ }
+
+ [Test]
+ public void NamedCounterTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets>
+ <target name='debug1' type='Debug' layout='${message} ${counter:sequence=aaa}' />
+ <target name='debug2' type='Debug' layout='${message} ${counter:sequence=bbb}' />
+ <target name='debug3' type='Debug' layout='${message} ${counter:sequence=aaa}' />
+ </targets>
+ <rules>
+ <logger name='debug1' minlevel='Debug' writeTo='debug1' />
+ <logger name='debug2' minlevel='Debug' writeTo='debug2' />
+ <logger name='debug3' minlevel='Debug' writeTo='debug3' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ LogManager.GetLogger("debug1").Debug("a");
+ AssertDebugLastMessage("debug1", "a 1");
+ LogManager.GetLogger("debug2").Debug("a");
+ AssertDebugLastMessage("debug2", "a 1");
+ LogManager.GetLogger("debug3").Debug("a");
+ AssertDebugLastMessage("debug3", "a 2");
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/DateTests.cs b/tests/NLog.UnitTests/LayoutRenderers/DateTests.cs
new file mode 100644
index 0000000..cff6b1e
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/DateTests.cs
@@ -0,0 +1,85 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class DateTests : NLogTestBase
+ {
+ [Test]
+ public void DefaultDateTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${date}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+ LogManager.GetLogger("d").Debug("zzz");
+ DateTime dt = DateTime.Parse(GetDebugLastMessage("debug"));
+ DateTime now = DateTime.Now;
+
+ Assert.IsTrue(Math.Abs((dt - now).TotalSeconds) < 5);
+ }
+
+ [Test]
+ public void FormattedDateTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${date:format=yyyy-MM-dd}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+ LogManager.GetLogger("d").Debug("zzz");
+ AssertDebugLastMessage("debug", DateTime.Now.ToString("yyyy-MM-dd"));
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/EnvironmentTests.cs b/tests/NLog.UnitTests/LayoutRenderers/EnvironmentTests.cs
new file mode 100644
index 0000000..045eb5c
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/EnvironmentTests.cs
@@ -0,0 +1,62 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class EnvironmentTests : NLogTestBase
+ {
+ [Test]
+ public void EnvironmentTest()
+ {
+ Layout l = new Layout("${environment:variable=PATH}");
+ AssertLayoutRendererOutput(l, System.Environment.GetEnvironmentVariable("PATH"));
+ }
+
+ [Test]
+ public void EnvironmentSimpleTest()
+ {
+ Layout l = new Layout("${environment:PATH}");
+ AssertLayoutRendererOutput(l, System.Environment.GetEnvironmentVariable("PATH"));
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/EventContextTests.cs b/tests/NLog.UnitTests/LayoutRenderers/EventContextTests.cs
new file mode 100644
index 0000000..bf1b8f5
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/EventContextTests.cs
@@ -0,0 +1,71 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class EventContextTests : NLogTestBase
+ {
+ [Test]
+ public void Test1()
+ {
+ Layout l = new Layout("${event-context:aaa}");
+ l.Initialize();
+ LogEventInfo lei = new LogEventInfo(LogLevel.Info, "aaa", "bbb");
+
+ // empty
+ Assert.AreEqual("", l.GetFormattedMessage(lei));
+ }
+
+ [Test]
+ public void Test2()
+ {
+ Layout l = new Layout("${event-context:aaa}");
+ LogEventInfo lei = new LogEventInfo(LogLevel.Info, "aaa", "bbb");
+ l.Initialize();
+ lei.Context["aaa"] = "bbb";
+
+ // empty
+ Assert.AreEqual("bbb", l.GetFormattedMessage(lei));
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/ExceptionTests.cs b/tests/NLog.UnitTests/LayoutRenderers/ExceptionTests.cs
new file mode 100644
index 0000000..6718059
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/ExceptionTests.cs
@@ -0,0 +1,89 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Globalization;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class ExceptionTests : NLogTestBase
+ {
+ [Test]
+ public void Test1()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets>
+ <target name='debug1' type='Debug' layout='${exception}' />
+ <target name='debug2' type='Debug' layout='${exception:format=stacktrace}' />
+ <target name='debug3' type='Debug' layout='${exception:format=type}' />
+ <target name='debug4' type='Debug' layout='${exception:format=shorttype}' />
+ <target name='debug5' type='Debug' layout='${exception:format=tostring}' />
+ <target name='debug6' type='Debug' layout='${exception:format=message}' />
+ <target name='debug7' type='Debug' layout='${exception:format=method}' />
+ <target name='debug8' type='Debug' layout='${exception:format=message,shorttype:separator=*}' />
+ </targets>
+ <rules>
+ <logger minlevel='Info' writeTo='debug1,debug2,debug3,debug4,debug5,debug6,debug7,debug8' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ try
+ {
+ throw new Exception("Test exception");
+ }
+ catch (Exception ex)
+ {
+ LogManager.GetCurrentClassLogger().ErrorException("msg", ex);
+ AssertDebugLastMessage("debug1", "Test exception");
+ AssertDebugLastMessage("debug2", ex.StackTrace);
+ AssertDebugLastMessage("debug3", typeof(Exception).FullName);
+ AssertDebugLastMessage("debug4", typeof(Exception).Name);
+ AssertDebugLastMessage("debug5", ex.ToString());
+ AssertDebugLastMessage("debug6", "Test exception");
+ AssertDebugLastMessage("debug7", ex.TargetSite.ToString());
+ AssertDebugLastMessage("debug8", "Test exception*Exception");
+ }
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/GDCTests.cs b/tests/NLog.UnitTests/LayoutRenderers/GDCTests.cs
new file mode 100644
index 0000000..371b17d
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/GDCTests.cs
@@ -0,0 +1,75 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class GDCTests : NLogTestBase
+ {
+ [Test]
+ public void GDCTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${gdc:item=myitem} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ NLog.GDC.Set("myitem", "myvalue");
+ LogManager.GetLogger("A").Debug("a");
+ AssertDebugLastMessage("debug", "myvalue a");
+
+ NLog.GDC.Set("myitem", "value2");
+ LogManager.GetLogger("A").Debug("b");
+ AssertDebugLastMessage("debug", "value2 b");
+
+ NLog.GDC.Remove("myitem");
+ LogManager.GetLogger("A").Debug("c");
+ AssertDebugLastMessage("debug", " c");
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/LiteralTests.cs b/tests/NLog.UnitTests/LayoutRenderers/LiteralTests.cs
new file mode 100644
index 0000000..cd119ce
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/LiteralTests.cs
@@ -0,0 +1,68 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+using System.IO;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class LiteralTests : NLogTestBase
+ {
+ [Test]
+ public void LiteralTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='abcd' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugLastMessage("debug", "abcd");
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/LogLevelTests.cs b/tests/NLog.UnitTests/LayoutRenderers/LogLevelTests.cs
new file mode 100644
index 0000000..9d9a17f
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/LogLevelTests.cs
@@ -0,0 +1,76 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+using System.IO;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class LogLevelTests : NLogTestBase
+ {
+ [Test]
+ public void LogLevelTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${level} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugLastMessage("debug", "Debug a");
+ logger.Info("a");
+ AssertDebugLastMessage("debug", "Info a");
+ logger.Warn("a");
+ AssertDebugLastMessage("debug", "Warn a");
+ logger.Error("a");
+ AssertDebugLastMessage("debug", "Error a");
+ logger.Fatal("a");
+ AssertDebugLastMessage("debug", "Fatal a");
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/LoggerNameTests.cs b/tests/NLog.UnitTests/LayoutRenderers/LoggerNameTests.cs
new file mode 100644
index 0000000..56fbce7
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/LoggerNameTests.cs
@@ -0,0 +1,67 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class LoggerNameTests : NLogTestBase
+ {
+ [Test]
+ public void LoggerNameTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${logger} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugLastMessage("debug", "A a");
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/LongDateTests.cs b/tests/NLog.UnitTests/LayoutRenderers/LongDateTests.cs
new file mode 100644
index 0000000..047e036
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/LongDateTests.cs
@@ -0,0 +1,91 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class LongDateTests : NLogTestBase
+ {
+ [Test]
+ public void LongDateTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${longdate}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+ LogManager.GetLogger("d").Debug("zzz");
+ string date = GetDebugLastMessage("debug");
+ Assert.AreEqual(date.Length, 24);
+ Assert.AreEqual(date[4], '-');
+ Assert.AreEqual(date[7], '-');
+ Assert.AreEqual(date[10], ' ');
+ Assert.AreEqual(date[13], ':');
+ Assert.AreEqual(date[16], ':');
+ Assert.AreEqual(date[19], '.');
+ }
+
+ [Test]
+ public void LongDateWithPadding()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${longdate:padding=5:fixedlength=true}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+ LogManager.GetLogger("d").Debug("zzz");
+ string date = GetDebugLastMessage("debug");
+ Assert.AreEqual(5, date.Length);
+ Assert.AreEqual(date[4], '-');
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/MDCTests.cs b/tests/NLog.UnitTests/LayoutRenderers/MDCTests.cs
new file mode 100644
index 0000000..f31a06c
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/MDCTests.cs
@@ -0,0 +1,75 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class MDCTests : NLogTestBase
+ {
+ [Test]
+ public void MDCTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${mdc:item=myitem} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ NLog.MDC.Set("myitem", "myvalue");
+ LogManager.GetLogger("A").Debug("a");
+ AssertDebugLastMessage("debug", "myvalue a");
+
+ NLog.MDC.Set("myitem", "value2");
+ LogManager.GetLogger("A").Debug("b");
+ AssertDebugLastMessage("debug", "value2 b");
+
+ NLog.MDC.Remove("myitem");
+ LogManager.GetLogger("A").Debug("c");
+ AssertDebugLastMessage("debug", " c");
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/MessageTests.cs b/tests/NLog.UnitTests/LayoutRenderers/MessageTests.cs
new file mode 100644
index 0000000..3c821d3
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/MessageTests.cs
@@ -0,0 +1,176 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+using System.Globalization;
+using System.IO;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class MessageTests : NLogTestBase
+ {
+ [Test]
+ public void MessageWithoutPaddingTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugLastMessage("debug", "a");
+ logger.Debug("a{0}", 1);
+ AssertDebugLastMessage("debug", "a1");
+ logger.Debug("a{0}{1}", 1, "2");
+ AssertDebugLastMessage("debug", "a12");
+ logger.Debug(CultureInfo.InvariantCulture, "a{0}", new DateTime(2005,1,1));
+ AssertDebugLastMessage("debug", "a01/01/2005 00:00:00");
+ }
+
+ [Test]
+ public void MessageRightPaddingTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message:padding=3}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugLastMessage("debug", " a");
+ logger.Debug("a{0}", 1);
+ AssertDebugLastMessage("debug", " a1");
+ logger.Debug("a{0}{1}", 1, "2");
+ AssertDebugLastMessage("debug", "a12");
+ logger.Debug(CultureInfo.InvariantCulture, "a{0}", new DateTime(2005,1,1));
+ AssertDebugLastMessage("debug", "a01/01/2005 00:00:00");
+ }
+
+
+ [Test]
+ public void MessageFixedLengthRightPaddingTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message:padding=3:fixedlength=true}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugLastMessage("debug", " a");
+ logger.Debug("a{0}", 1);
+ AssertDebugLastMessage("debug", " a1");
+ logger.Debug("a{0}{1}", 1, "2");
+ AssertDebugLastMessage("debug", "a12");
+ logger.Debug(CultureInfo.InvariantCulture, "a{0}", new DateTime(2005,1,1));
+ AssertDebugLastMessage("debug", "a01");
+ }
+
+ [Test]
+ public void MessageLeftPaddingTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message:padding=-3:padcharacter=x}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugLastMessage("debug", "axx");
+ logger.Debug("a{0}", 1);
+ AssertDebugLastMessage("debug", "a1x");
+ logger.Debug("a{0}{1}", 1, "2");
+ AssertDebugLastMessage("debug", "a12");
+ logger.Debug(CultureInfo.InvariantCulture, "a{0}", new DateTime(2005,1,1));
+ AssertDebugLastMessage("debug", "a01/01/2005 00:00:00");
+ }
+
+ [Test]
+ public void MessageFixedLengthLeftPaddingTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message:padding=-3:padcharacter=x:fixedlength=true}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("a");
+ AssertDebugLastMessage("debug", "axx");
+ logger.Debug("a{0}", 1);
+ AssertDebugLastMessage("debug", "a1x");
+ logger.Debug("a{0}{1}", 1, "2");
+ AssertDebugLastMessage("debug", "a12");
+ logger.Debug(CultureInfo.InvariantCulture, "a{0}", new DateTime(2005,1,1));
+ AssertDebugLastMessage("debug", "a01");
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/NDCTests.cs b/tests/NLog.UnitTests/LayoutRenderers/NDCTests.cs
new file mode 100644
index 0000000..344339c
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/NDCTests.cs
@@ -0,0 +1,286 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class NDCTests : NLogTestBase
+ {
+ [Test]
+ public void NDCTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${ndc} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ LogManager.GetLogger("A").Debug("0");
+ AssertDebugLastMessage("debug", " 0");
+ using (NLog.NDC.Push("ala"))
+ {
+ LogManager.GetLogger("A").Debug("a");
+ AssertDebugLastMessage("debug", "ala a");
+ using (NLog.NDC.Push("ma"))
+ {
+ LogManager.GetLogger("A").Debug("b");
+ AssertDebugLastMessage("debug", "ala ma b");
+ using (NLog.NDC.Push("kota"))
+ {
+ LogManager.GetLogger("A").Debug("c");
+ AssertDebugLastMessage("debug", "ala ma kota c");
+ using (NLog.NDC.Push("kopytko"))
+ {
+ LogManager.GetLogger("A").Debug("d");
+ AssertDebugLastMessage("debug", "ala ma kota kopytko d");
+ }
+ LogManager.GetLogger("A").Debug("c");
+ AssertDebugLastMessage("debug", "ala ma kota c");
+ }
+ LogManager.GetLogger("A").Debug("b");
+ AssertDebugLastMessage("debug", "ala ma b");
+ }
+ LogManager.GetLogger("A").Debug("a");
+ AssertDebugLastMessage("debug", "ala a");
+ }
+ LogManager.GetLogger("A").Debug("0");
+ AssertDebugLastMessage("debug", " 0");
+ }
+
+ [Test]
+ public void NDCTopTestTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${ndc:topframes=2} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ LogManager.GetLogger("A").Debug("0");
+ AssertDebugLastMessage("debug", " 0");
+ using (NLog.NDC.Push("ala"))
+ {
+ LogManager.GetLogger("A").Debug("a");
+ AssertDebugLastMessage("debug", "ala a");
+ using (NLog.NDC.Push("ma"))
+ {
+ LogManager.GetLogger("A").Debug("b");
+ AssertDebugLastMessage("debug", "ala ma b");
+ using (NLog.NDC.Push("kota"))
+ {
+ LogManager.GetLogger("A").Debug("c");
+ AssertDebugLastMessage("debug", "ma kota c");
+ using (NLog.NDC.Push("kopytko"))
+ {
+ LogManager.GetLogger("A").Debug("d");
+ AssertDebugLastMessage("debug", "kota kopytko d");
+ }
+ LogManager.GetLogger("A").Debug("c");
+ AssertDebugLastMessage("debug", "ma kota c");
+ }
+ LogManager.GetLogger("A").Debug("b");
+ AssertDebugLastMessage("debug", "ala ma b");
+ }
+ LogManager.GetLogger("A").Debug("a");
+ AssertDebugLastMessage("debug", "ala a");
+ }
+ LogManager.GetLogger("A").Debug("0");
+ AssertDebugLastMessage("debug", " 0");
+ }
+
+
+ [Test]
+ public void NDCTop1TestTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${ndc:topframes=1} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ LogManager.GetLogger("A").Debug("0");
+ AssertDebugLastMessage("debug", " 0");
+ using (NLog.NDC.Push("ala"))
+ {
+ LogManager.GetLogger("A").Debug("a");
+ AssertDebugLastMessage("debug", "ala a");
+ using (NLog.NDC.Push("ma"))
+ {
+ LogManager.GetLogger("A").Debug("b");
+ AssertDebugLastMessage("debug", "ma b");
+ using (NLog.NDC.Push("kota"))
+ {
+ LogManager.GetLogger("A").Debug("c");
+ AssertDebugLastMessage("debug", "kota c");
+ NLog.NDC.Push("kopytko");
+ LogManager.GetLogger("A").Debug("d");
+ AssertDebugLastMessage("debug", "kopytko d");
+ Assert.AreEqual("kopytko", NLog.NDC.Pop()); // manual pop
+ LogManager.GetLogger("A").Debug("c");
+ AssertDebugLastMessage("debug", "kota c");
+ }
+ LogManager.GetLogger("A").Debug("b");
+ AssertDebugLastMessage("debug", "ma b");
+ }
+ LogManager.GetLogger("A").Debug("a");
+ AssertDebugLastMessage("debug", "ala a");
+ }
+ LogManager.GetLogger("A").Debug("0");
+ AssertDebugLastMessage("debug", " 0");
+ Assert.AreEqual(String.Empty, NLog.NDC.Pop());
+ Assert.AreEqual(String.Empty, NLog.NDC.GetTopMessage());
+ NLog.NDC.Push("zzz");
+ Assert.AreEqual("zzz", NLog.NDC.GetTopMessage());
+ NLog.NDC.Clear();
+ Assert.AreEqual(String.Empty, NLog.NDC.Pop());
+ Assert.AreEqual(String.Empty, NLog.NDC.GetTopMessage());
+ }
+
+ [Test]
+ public void NDCBottomTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${ndc:bottomframes=2} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ LogManager.GetLogger("A").Debug("0");
+ AssertDebugLastMessage("debug", " 0");
+ using (NLog.NDC.Push("ala"))
+ {
+ LogManager.GetLogger("A").Debug("a");
+ AssertDebugLastMessage("debug", "ala a");
+ using (NLog.NDC.Push("ma"))
+ {
+ LogManager.GetLogger("A").Debug("b");
+ AssertDebugLastMessage("debug", "ala ma b");
+ using (NLog.NDC.Push("kota"))
+ {
+ LogManager.GetLogger("A").Debug("c");
+ AssertDebugLastMessage("debug", "ala ma c");
+ using (NLog.NDC.Push("kopytko"))
+ {
+ LogManager.GetLogger("A").Debug("d");
+ AssertDebugLastMessage("debug", "ala ma d");
+ }
+ LogManager.GetLogger("A").Debug("c");
+ AssertDebugLastMessage("debug", "ala ma c");
+ }
+ LogManager.GetLogger("A").Debug("b");
+ AssertDebugLastMessage("debug", "ala ma b");
+ }
+ LogManager.GetLogger("A").Debug("a");
+ AssertDebugLastMessage("debug", "ala a");
+ }
+ LogManager.GetLogger("A").Debug("0");
+ AssertDebugLastMessage("debug", " 0");
+ }
+
+ [Test]
+ public void NDCSeparatorTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${ndc:separator=\:} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ LogManager.GetLogger("A").Debug("0");
+ AssertDebugLastMessage("debug", " 0");
+ using (NLog.NDC.Push("ala"))
+ {
+ LogManager.GetLogger("A").Debug("a");
+ AssertDebugLastMessage("debug", "ala a");
+ using (NLog.NDC.Push("ma"))
+ {
+ LogManager.GetLogger("A").Debug("b");
+ AssertDebugLastMessage("debug", "ala:ma b");
+ using (NLog.NDC.Push("kota"))
+ {
+ LogManager.GetLogger("A").Debug("c");
+ AssertDebugLastMessage("debug", "ala:ma:kota c");
+ using (NLog.NDC.Push("kopytko"))
+ {
+ LogManager.GetLogger("A").Debug("d");
+ AssertDebugLastMessage("debug", "ala:ma:kota:kopytko d");
+ }
+ LogManager.GetLogger("A").Debug("c");
+ AssertDebugLastMessage("debug", "ala:ma:kota c");
+ }
+ LogManager.GetLogger("A").Debug("b");
+ AssertDebugLastMessage("debug", "ala:ma b");
+ }
+ LogManager.GetLogger("A").Debug("a");
+ AssertDebugLastMessage("debug", "ala a");
+ }
+ LogManager.GetLogger("A").Debug("0");
+ AssertDebugLastMessage("debug", " 0");
+ }
+
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/Rot13Tests.cs b/tests/NLog.UnitTests/LayoutRenderers/Rot13Tests.cs
new file mode 100644
index 0000000..2ccc575
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/Rot13Tests.cs
@@ -0,0 +1,113 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+using NLog.LayoutRenderers;
+using NLog.Targets;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class Rot13Tests : NLogTestBase
+ {
+ [Test]
+ public void Test1()
+ {
+ Assert.AreEqual("NOPQRSTUVWXYZABCDEFGHIJKLM",
+ Rot13LayoutRenderer.DecodeRot13("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+ Assert.AreEqual("nopqrstuvwxyzabcdefghijklm0123456789",
+ Rot13LayoutRenderer.DecodeRot13("abcdefghijklmnopqrstuvwxyz0123456789"));
+ Assert.AreEqual("How can you tell an extrovert from an introvert at NSA? Va gur ryringbef, gur rkgebiregf ybbx ng gur BGURE thl'f fubrf.",
+ Rot13LayoutRenderer.DecodeRot13(
+ "Ubj pna lbh gryy na rkgebireg sebz na vagebireg ng AFN? In the elevators, the extroverts look at the OTHER guy's shoes."));
+ }
+
+ [Test]
+ public void Test2()
+ {
+ Layout l = new Layout("${rot13:HELLO}");
+ LogEventInfo lei = new LogEventInfo(LogLevel.Info, "aaa", "bbb");
+ Assert.AreEqual("URYYB", l.GetFormattedMessage(lei));
+ }
+
+ [Test]
+ public void Test3()
+ {
+ Layout l = new Layout("${rot13:text=HELLO}");
+ LogEventInfo lei = new LogEventInfo(LogLevel.Info, "aaa", "bbb");
+ Assert.AreEqual("URYYB", l.GetFormattedMessage(lei));
+ }
+
+ [Test]
+ public void Test4()
+ {
+ Layout l = new Layout("${rot13:${event-context:aaa}}");
+ LogEventInfo lei = new LogEventInfo(LogLevel.Info, "aaa", "bbb");
+ lei.Context["aaa"] = "HELLO";
+ Assert.AreEqual("URYYB", l.GetFormattedMessage(lei));
+ }
+
+ [Test]
+ public void Test5()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets>
+ <target name='debug' type='Debug' layout='${rot13:${callsite:methodname=false}}' />
+ <target name='debug2' type='Debug' layout='${rot13:${rot13:${callsite:methodname=false}}}' />
+ </targets>
+ <rules>
+ <logger name='*' levels='Trace' writeTo='debug,debug2' />
+ </rules>
+ </nlog>");
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger l = LogManager.GetCurrentClassLogger();
+ l.Trace("aaa");
+ // this is the rot-13-fied name of current class
+ AssertDebugLastMessage("debug", "AYbt.HavgGrfgf.YnlbhgEraqreref.Ebg13Grfgf");
+
+ // double rot-13 should be identity
+ AssertDebugLastMessage("debug2", "NLog.UnitTests.LayoutRenderers.Rot13Tests");
+
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/ShortDateTests.cs b/tests/NLog.UnitTests/LayoutRenderers/ShortDateTests.cs
new file mode 100644
index 0000000..a68995e
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/ShortDateTests.cs
@@ -0,0 +1,65 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class ShortDateTests : NLogTestBase
+ {
+ [Test]
+ public void ShortDateTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${shortdate}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+ LogManager.GetLogger("d").Debug("zzz");
+ AssertDebugLastMessage("debug", DateTime.Now.ToString("yyyy-MM-dd"));
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LayoutRenderers/ThreadNameTests.cs b/tests/NLog.UnitTests/LayoutRenderers/ThreadNameTests.cs
new file mode 100644
index 0000000..9b99ddd
--- /dev/null
+++ b/tests/NLog.UnitTests/LayoutRenderers/ThreadNameTests.cs
@@ -0,0 +1,69 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Reflection;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests.LayoutRenderers
+{
+ [TestFixture]
+ public class ThreadNameTests : NLogTestBase
+ {
+ [Test]
+ public void ThreadNameTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${threadname} ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ if (System.Threading.Thread.CurrentThread.Name == null)
+ System.Threading.Thread.CurrentThread.Name = "mythreadname";
+
+ LogManager.GetLogger("A").Debug("a");
+ AssertDebugLastMessage("debug", System.Threading.Thread.CurrentThread.Name + " a");
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LogLevelTests.cs b/tests/NLog.UnitTests/LogLevelTests.cs
new file mode 100644
index 0000000..bf657eb
--- /dev/null
+++ b/tests/NLog.UnitTests/LogLevelTests.cs
@@ -0,0 +1,134 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Globalization;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests
+{
+ [TestFixture]
+ public class LogLevelTests : NLogTestBase
+ {
+ [Test]
+ public void OrdinalTest()
+ {
+ Assert.IsTrue(LogLevel.Trace < LogLevel.Debug);
+ Assert.IsTrue(LogLevel.Debug < LogLevel.Info);
+ Assert.IsTrue(LogLevel.Info < LogLevel.Warn);
+ Assert.IsTrue(LogLevel.Warn < LogLevel.Error);
+ Assert.IsTrue(LogLevel.Error < LogLevel.Fatal);
+ Assert.IsTrue(LogLevel.Fatal < LogLevel.Off);
+
+ Assert.IsFalse(LogLevel.Trace > LogLevel.Debug);
+ Assert.IsFalse(LogLevel.Debug > LogLevel.Info);
+ Assert.IsFalse(LogLevel.Info > LogLevel.Warn);
+ Assert.IsFalse(LogLevel.Warn > LogLevel.Error);
+ Assert.IsFalse(LogLevel.Error > LogLevel.Fatal);
+ Assert.IsFalse(LogLevel.Fatal > LogLevel.Off);
+
+ Assert.IsTrue(LogLevel.Trace <= LogLevel.Debug);
+ Assert.IsTrue(LogLevel.Debug <= LogLevel.Info);
+ Assert.IsTrue(LogLevel.Info <= LogLevel.Warn);
+ Assert.IsTrue(LogLevel.Warn <= LogLevel.Error);
+ Assert.IsTrue(LogLevel.Error <= LogLevel.Fatal);
+ Assert.IsTrue(LogLevel.Fatal <= LogLevel.Off);
+
+ Assert.IsFalse(LogLevel.Trace >= LogLevel.Debug);
+ Assert.IsFalse(LogLevel.Debug >= LogLevel.Info);
+ Assert.IsFalse(LogLevel.Info >= LogLevel.Warn);
+ Assert.IsFalse(LogLevel.Warn >= LogLevel.Error);
+ Assert.IsFalse(LogLevel.Error >= LogLevel.Fatal);
+ Assert.IsFalse(LogLevel.Fatal >= LogLevel.Off);
+ }
+
+ [Test]
+ public void FromStringTest()
+ {
+ Assert.AreSame(LogLevel.FromString("trace"), LogLevel.Trace);
+ Assert.AreSame(LogLevel.FromString("debug"), LogLevel.Debug);
+ Assert.AreSame(LogLevel.FromString("info"), LogLevel.Info);
+ Assert.AreSame(LogLevel.FromString("warn"), LogLevel.Warn);
+ Assert.AreSame(LogLevel.FromString("error"), LogLevel.Error);
+ Assert.AreSame(LogLevel.FromString("fatal"), LogLevel.Fatal);
+ Assert.AreSame(LogLevel.FromString("off"), LogLevel.Off);
+
+ Assert.AreSame(LogLevel.FromString("Trace"), LogLevel.Trace);
+ Assert.AreSame(LogLevel.FromString("Debug"), LogLevel.Debug);
+ Assert.AreSame(LogLevel.FromString("Info"), LogLevel.Info);
+ Assert.AreSame(LogLevel.FromString("Warn"), LogLevel.Warn);
+ Assert.AreSame(LogLevel.FromString("Error"), LogLevel.Error);
+ Assert.AreSame(LogLevel.FromString("Fatal"), LogLevel.Fatal);
+ Assert.AreSame(LogLevel.FromString("Off"), LogLevel.Off);
+
+ Assert.AreSame(LogLevel.FromString("TracE"), LogLevel.Trace);
+ Assert.AreSame(LogLevel.FromString("DebuG"), LogLevel.Debug);
+ Assert.AreSame(LogLevel.FromString("InfO"), LogLevel.Info);
+ Assert.AreSame(LogLevel.FromString("WarN"), LogLevel.Warn);
+ Assert.AreSame(LogLevel.FromString("ErroR"), LogLevel.Error);
+ Assert.AreSame(LogLevel.FromString("FataL"), LogLevel.Fatal);
+
+ Assert.AreSame(LogLevel.FromString("TRACE"), LogLevel.Trace);
+ Assert.AreSame(LogLevel.FromString("DEBUG"), LogLevel.Debug);
+ Assert.AreSame(LogLevel.FromString("INFO"), LogLevel.Info);
+ Assert.AreSame(LogLevel.FromString("WARN"), LogLevel.Warn);
+ Assert.AreSame(LogLevel.FromString("ERROR"), LogLevel.Error);
+ Assert.AreSame(LogLevel.FromString("FATAL"), LogLevel.Fatal);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentException))]
+ public void FromStringFailingTest()
+ {
+ LogLevel l = LogLevel.FromString("zzz");
+ }
+
+ [Test]
+ public void ToStringTest()
+ {
+ Assert.AreEqual(LogLevel.Trace.ToString(), "Trace");
+ Assert.AreEqual(LogLevel.Debug.ToString(), "Debug");
+ Assert.AreEqual(LogLevel.Info.ToString(), "Info");
+ Assert.AreEqual(LogLevel.Warn.ToString(), "Warn");
+ Assert.AreEqual(LogLevel.Error.ToString(), "Error");
+ Assert.AreEqual(LogLevel.Fatal.ToString(), "Fatal");
+ }
+ }
+
+
+}
diff --git a/tests/NLog.UnitTests/LogManagerTests.cs b/tests/NLog.UnitTests/LogManagerTests.cs
new file mode 100644
index 0000000..50fde9b
--- /dev/null
+++ b/tests/NLog.UnitTests/LogManagerTests.cs
@@ -0,0 +1,320 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Globalization;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+using NLog.Targets;
+using System.IO;
+using System.Threading;
+
+using NLog.Internal;
+
+namespace NLog.UnitTests
+{
+ [TestFixture]
+ public class LogManagerTests : NLogTestBase
+ {
+ [Test]
+ public void GetLoggerTest()
+ {
+ Logger loggerA = LogManager.GetLogger("A");
+ Logger loggerA2 = LogManager.GetLogger("A");
+ Logger loggerB = LogManager.GetLogger("B");
+ Assert.AreSame(loggerA, loggerA2);
+ Assert.AreNotSame(loggerA, loggerB);
+ Assert.AreEqual("A", loggerA.Name);
+ Assert.AreEqual("B", loggerB.Name);
+ }
+
+ [Test]
+ public void NullLoggerTest()
+ {
+ Logger l = LogManager.CreateNullLogger();
+ Assert.AreEqual("", l.Name);
+ }
+
+ [Test]
+ public void ThrowExceptionsTest()
+ {
+ FileTarget ft = new FileTarget();
+ ft.FileName = ""; // invalid file name
+ SimpleConfigurator.ConfigureForTargetLogging(ft);
+ LogManager.ThrowExceptions = false;
+ LogManager.GetLogger("A").Info("a");
+ LogManager.ThrowExceptions = true;
+ try
+ {
+ LogManager.GetLogger("A").Info("a");
+ Assert.Fail("Should not be reached.");
+ }
+ catch
+ {
+ Assert.IsTrue(true);
+ }
+ LogManager.ThrowExceptions = false;
+ }
+
+ public void GlobalThresholdTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog globalThreshold='Info'>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Assert.AreEqual(LogLevel.Info, LogManager.GlobalThreshold);
+
+ // nothing gets logged because of globalThreshold
+ LogManager.GetLogger("A").Debug("xxx");
+ AssertDebugLastMessage("debug", "");
+
+ // lower the threshold
+ LogManager.GlobalThreshold = LogLevel.Trace;
+
+ LogManager.GetLogger("A").Debug("yyy");
+ AssertDebugLastMessage("debug", "yyy");
+
+ // raise the threshold
+ LogManager.GlobalThreshold = LogLevel.Info;
+
+ // this should be yyy, meaning that the target is in place
+ // only rules have been modified.
+
+ LogManager.GetLogger("A").Debug("zzz");
+ AssertDebugLastMessage("debug", "yyy");
+ }
+
+ private int _reloadCounter = 0;
+
+ private void OnConfigReloaded(bool success, Exception ex)
+ {
+ Console.WriteLine("OnConfigReloaded success={0}", success);
+ _reloadCounter++;
+ }
+
+ private void WaitForConfigReload(int counter)
+ {
+ while (_reloadCounter < counter)
+ {
+ System.Threading.Thread.Sleep(100);
+ }
+ }
+
+ [Test]
+ [Category("LongRunning")]
+ public void AutoReloadTest()
+ {
+ string fileName = Path.GetTempFileName();
+ try
+ {
+ _reloadCounter = 0;
+ LogManager.ConfigurationReloaded += new LoggingConfigurationReloaded(OnConfigReloaded);
+ using (StreamWriter fs = File.CreateText(fileName))
+ {
+ fs.Write(@"<nlog autoReload='true'>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+ LogManager.Configuration = new XmlLoggingConfiguration(fileName);
+ AssertDebugCounter("debug", 0);
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("aaa");
+ AssertDebugLastMessage("debug", "aaa");
+
+ InternalLogger.Info("Rewriting test file...");
+
+ // now write the file again
+ using (StreamWriter fs = File.CreateText(fileName))
+ {
+ fs.Write(@"<nlog autoReload='true'>
+ <targets><target name='debug' type='Debug' layout='xxx ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+
+ InternalLogger.Info("Rewritten.");
+ WaitForConfigReload(1);
+
+ logger.Debug("aaa");
+ AssertDebugLastMessage("debug", "xxx aaa");
+
+ // write the file again, this time make an error
+ using (StreamWriter fs = File.CreateText(fileName))
+ {
+ fs.Write(@"<nlog autoReload='true'>
+ <targets><tar get name='debug' type='Debug' layout='xxx ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+
+ WaitForConfigReload(2);
+ logger.Debug("bbb");
+ AssertDebugLastMessage("debug", "xxx bbb");
+
+ // write the corrected file again
+ using (StreamWriter fs = File.CreateText(fileName))
+ {
+ fs.Write(@"<nlog autoReload='true'>
+ <targets><target name='debug' type='Debug' layout='zzz ${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+ WaitForConfigReload(3);
+ logger.Debug("ccc");
+ AssertDebugLastMessage("debug", "zzz ccc");
+
+ }
+ finally
+ {
+ LogManager.ConfigurationReloaded -= new LoggingConfigurationReloaded(OnConfigReloaded);
+ LogManager.Configuration = null;
+ if (File.Exists(fileName))
+ File.Delete(fileName);
+ }
+ }
+
+ [Test]
+ public void IncludeTest()
+ {
+ string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
+ Directory.CreateDirectory(tempPath);
+ try
+ {
+ using (StreamWriter fs = File.CreateText(Path.Combine(tempPath, "included.nlog")))
+ {
+ fs.Write(@"<nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ </nlog>");
+ }
+
+ using (StreamWriter fs = File.CreateText(Path.Combine(tempPath, "main.nlog")))
+ {
+ fs.Write(@"<nlog>
+ <include file='included.nlog' />
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+
+ LogManager.Configuration = new XmlLoggingConfiguration(Path.Combine(tempPath, "main.nlog"));
+ LogManager.GetLogger("A").Debug("aaa");
+ AssertDebugLastMessage("debug", "aaa");
+ }
+ finally
+ {
+ LogManager.Configuration = null;
+ if (Directory.Exists(tempPath))
+ Directory.Delete(tempPath, true);
+ }
+ }
+
+ [Test]
+ [ExpectedException(typeof(NLogConfigurationException))]
+ public void IncludeNotExistingTest()
+ {
+ string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
+ Directory.CreateDirectory(tempPath);
+
+ try
+ {
+ using (StreamWriter fs = File.CreateText(Path.Combine(tempPath, "main.nlog")))
+ {
+ fs.Write(@"<nlog>
+ <include file='included.nlog' />
+ </nlog>");
+ }
+
+ LogManager.Configuration = new XmlLoggingConfiguration(Path.Combine(tempPath, "main.nlog"));
+ }
+ finally
+ {
+ LogManager.Configuration = null;
+ if (Directory.Exists(tempPath))
+ Directory.Delete(tempPath, true);
+ }
+ }
+
+ [Test]
+ [ExpectedException(typeof(NLogConfigurationException))]
+ public void IncludeNotExistingIgnoredTest()
+ {
+ string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
+ Directory.CreateDirectory(tempPath);
+
+ try
+ {
+ using (StreamWriter fs = File.CreateText(Path.Combine(tempPath, "main.nlog")))
+ {
+ fs.Write(@"<nlog>
+ <include file='included-notpresent.nlog' />
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+
+ LogManager.Configuration = new XmlLoggingConfiguration(Path.Combine(tempPath, "main.nlog"));
+ LogManager.GetLogger("A").Debug("aaa");
+ AssertDebugLastMessage("debug", "aaa");
+ }
+ finally
+ {
+ LogManager.Configuration = null;
+ if (Directory.Exists(tempPath))
+ Directory.Delete(tempPath, true);
+ }
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/LoggerTests.cs b/tests/NLog.UnitTests/LoggerTests.cs
new file mode 100644
index 0000000..0a7349c
--- /dev/null
+++ b/tests/NLog.UnitTests/LoggerTests.cs
@@ -0,0 +1,1251 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Globalization;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests
+{
+ [TestFixture]
+ public class LoggerTests : NLogTestBase
+ {
+ [Test]
+ public void TraceTest()
+ {
+ // test all possible overloads of the Trace() method
+
+ for (int enabled = 0; enabled < 2; ++enabled)
+ {
+ XmlDocument doc = new XmlDocument();
+ if (enabled == 0)
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+ else
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='Trace' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+
+ logger.Trace("message");
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ logger.Trace("message{0}", (ulong)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", (ulong)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Trace("message{0}", (long)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", (long)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Trace("message{0}", (uint)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", (uint)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Trace("message{0}", (int)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", (int)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Trace("message{0}", (ushort)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", (ushort)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Trace("message{0}", (sbyte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", (sbyte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Trace("message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Trace("message{0}", (short)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", (short)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Trace("message{0}", (byte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", (byte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Trace("message{0}", 'c');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messagec");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", 'd');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messaged");
+
+ logger.Trace("message{0}", "ddd");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee");
+
+ logger.Trace("message{0}{1}", "ddd", 1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}{1}", "eee", 2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2");
+
+ logger.Trace("message{0}{1}{2}", "ddd", 1, "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1eee");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}{1}{2}", "eee", 2, "fff");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fff");
+
+ logger.Trace("message{0}{1}{2}{3}", "eee", 2, "fff", "ggg");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fffggg");
+
+ logger.Trace("message{0}", true);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageTrue");
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", false);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageFalse");
+
+ CultureInfo oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Trace("message{0}", (float)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", (float)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Trace((double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Trace(CultureInfo.InvariantCulture, (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1.5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Trace("message{0}", (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", (double)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Trace("message{0}", (decimal)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Trace(CultureInfo.InvariantCulture, "message{0}", (decimal)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ logger.TraceException("message", new Exception("test"));
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ if (enabled == 0)
+ AssertDebugCounter("debug", 0);
+ }
+ }
+
+ [Test]
+ public void DebugTest()
+ {
+ // test all possible overloads of the Debug() method
+
+ for (int enabled = 0; enabled < 2; ++enabled)
+ {
+ XmlDocument doc = new XmlDocument();
+ if (enabled == 0)
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+ else
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='Debug' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+
+ logger.Debug("message");
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ logger.Debug("message{0}", (ulong)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", (ulong)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Debug("message{0}", (long)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", (long)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Debug("message{0}", (uint)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", (uint)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Debug("message{0}", (int)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", (int)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Debug("message{0}", (ushort)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", (ushort)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Debug("message{0}", (sbyte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", (sbyte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Debug("message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Debug("message{0}", (short)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", (short)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Debug("message{0}", (byte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", (byte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Debug("message{0}", 'c');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messagec");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", 'd');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messaged");
+
+ logger.Debug("message{0}", "ddd");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee");
+
+ logger.Debug("message{0}{1}", "ddd", 1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}{1}", "eee", 2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2");
+
+ logger.Debug("message{0}{1}{2}", "ddd", 1, "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1eee");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}{1}{2}", "eee", 2, "fff");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fff");
+
+ logger.Debug("message{0}{1}{2}{3}", "eee", 2, "fff", "ggg");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fffggg");
+
+ logger.Debug("message{0}", true);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageTrue");
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", false);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageFalse");
+
+ CultureInfo oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Debug("message{0}", (float)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", (float)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Debug((double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Debug(CultureInfo.InvariantCulture, (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1.5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Debug("message{0}", (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", (double)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Debug("message{0}", (decimal)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Debug(CultureInfo.InvariantCulture, "message{0}", (decimal)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ logger.DebugException("message", new Exception("test"));
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ if (enabled == 0)
+ AssertDebugCounter("debug", 0);
+ }
+ }
+
+ [Test]
+ public void InfoTest()
+ {
+ // test all possible overloads of the Info() method
+
+ for (int enabled = 0; enabled < 2; ++enabled)
+ {
+ XmlDocument doc = new XmlDocument();
+ if (enabled == 0)
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+ else
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='Info' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+
+ logger.Info("message");
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ logger.Info("message{0}", (ulong)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", (ulong)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Info("message{0}", (long)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", (long)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Info("message{0}", (uint)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", (uint)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Info("message{0}", (int)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", (int)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Info("message{0}", (ushort)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", (ushort)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Info("message{0}", (sbyte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", (sbyte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Info("message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Info("message{0}", (short)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", (short)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Info("message{0}", (byte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", (byte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Info("message{0}", 'c');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messagec");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", 'd');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messaged");
+
+ logger.Info("message{0}", "ddd");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee");
+
+ logger.Info("message{0}{1}", "ddd", 1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}{1}", "eee", 2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2");
+
+ logger.Info("message{0}{1}{2}", "ddd", 1, "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1eee");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}{1}{2}", "eee", 2, "fff");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fff");
+
+ logger.Info("message{0}{1}{2}{3}", "eee", 2, "fff", "ggg");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fffggg");
+
+ logger.Info("message{0}", true);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageTrue");
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", false);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageFalse");
+
+ CultureInfo oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Info("message{0}", (float)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", (float)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Info((double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Info(CultureInfo.InvariantCulture, (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1.5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Info("message{0}", (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", (double)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Info("message{0}", (decimal)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Info(CultureInfo.InvariantCulture, "message{0}", (decimal)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ logger.InfoException("message", new Exception("test"));
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ if (enabled == 0)
+ AssertDebugCounter("debug", 0);
+ }
+ }
+
+ [Test]
+ public void WarnTest()
+ {
+ // test all possible overloads of the Warn() method
+
+ for (int enabled = 0; enabled < 2; ++enabled)
+ {
+ XmlDocument doc = new XmlDocument();
+ if (enabled == 0)
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+ else
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='Warn' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+
+ logger.Warn("message");
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ logger.Warn("message{0}", (ulong)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", (ulong)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Warn("message{0}", (long)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", (long)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Warn("message{0}", (uint)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", (uint)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Warn("message{0}", (int)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", (int)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Warn("message{0}", (ushort)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", (ushort)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Warn("message{0}", (sbyte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", (sbyte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Warn("message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Warn("message{0}", (short)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", (short)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Warn("message{0}", (byte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", (byte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Warn("message{0}", 'c');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messagec");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", 'd');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messaged");
+
+ logger.Warn("message{0}", "ddd");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee");
+
+ logger.Warn("message{0}{1}", "ddd", 1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}{1}", "eee", 2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2");
+
+ logger.Warn("message{0}{1}{2}", "ddd", 1, "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1eee");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}{1}{2}", "eee", 2, "fff");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fff");
+
+ logger.Warn("message{0}{1}{2}{3}", "eee", 2, "fff", "ggg");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fffggg");
+
+ logger.Warn("message{0}", true);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageTrue");
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", false);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageFalse");
+
+ CultureInfo oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Warn("message{0}", (float)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", (float)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Warn((double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Warn(CultureInfo.InvariantCulture, (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1.5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Warn("message{0}", (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", (double)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Warn("message{0}", (decimal)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Warn(CultureInfo.InvariantCulture, "message{0}", (decimal)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ logger.WarnException("message", new Exception("test"));
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ if (enabled == 0)
+ AssertDebugCounter("debug", 0);
+ }
+ }
+
+ [Test]
+ public void ErrorTest()
+ {
+ // test all possible overloads of the Error() method
+
+ for (int enabled = 0; enabled < 2; ++enabled)
+ {
+ XmlDocument doc = new XmlDocument();
+ if (enabled == 0)
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+ else
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='Error' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+
+ logger.Error("message");
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ logger.Error("message{0}", (ulong)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", (ulong)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Error("message{0}", (long)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", (long)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Error("message{0}", (uint)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", (uint)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Error("message{0}", (int)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", (int)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Error("message{0}", (ushort)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", (ushort)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Error("message{0}", (sbyte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", (sbyte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Error("message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Error("message{0}", (short)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", (short)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Error("message{0}", (byte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", (byte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Error("message{0}", 'c');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messagec");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", 'd');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messaged");
+
+ logger.Error("message{0}", "ddd");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee");
+
+ logger.Error("message{0}{1}", "ddd", 1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}{1}", "eee", 2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2");
+
+ logger.Error("message{0}{1}{2}", "ddd", 1, "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1eee");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}{1}{2}", "eee", 2, "fff");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fff");
+
+ logger.Error("message{0}{1}{2}{3}", "eee", 2, "fff", "ggg");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fffggg");
+
+ logger.Error("message{0}", true);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageTrue");
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", false);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageFalse");
+
+ CultureInfo oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Error("message{0}", (float)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", (float)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Error((double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Error(CultureInfo.InvariantCulture, (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1.5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Error("message{0}", (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", (double)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Error("message{0}", (decimal)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Error(CultureInfo.InvariantCulture, "message{0}", (decimal)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ logger.ErrorException("message", new Exception("test"));
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ if (enabled == 0)
+ AssertDebugCounter("debug", 0);
+ }
+ }
+
+ [Test]
+ public void FatalTest()
+ {
+ // test all possible overloads of the Fatal() method
+
+ for (int enabled = 0; enabled < 2; ++enabled)
+ {
+ XmlDocument doc = new XmlDocument();
+ if (enabled == 0)
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+ else
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='Fatal' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+
+ logger.Fatal("message");
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ logger.Fatal("message{0}", (ulong)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", (ulong)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Fatal("message{0}", (long)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", (long)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Fatal("message{0}", (uint)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", (uint)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Fatal("message{0}", (int)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", (int)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Fatal("message{0}", (ushort)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", (ushort)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Fatal("message{0}", (sbyte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", (sbyte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Fatal("message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Fatal("message{0}", (short)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", (short)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Fatal("message{0}", (byte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", (byte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Fatal("message{0}", 'c');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messagec");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", 'd');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messaged");
+
+ logger.Fatal("message{0}", "ddd");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee");
+
+ logger.Fatal("message{0}{1}", "ddd", 1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}{1}", "eee", 2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2");
+
+ logger.Fatal("message{0}{1}{2}", "ddd", 1, "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1eee");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}{1}{2}", "eee", 2, "fff");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fff");
+
+ logger.Fatal("message{0}{1}{2}{3}", "eee", 2, "fff", "ggg");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fffggg");
+
+ logger.Fatal("message{0}", true);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageTrue");
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", false);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageFalse");
+
+ CultureInfo oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Fatal("message{0}", (float)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", (float)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Fatal((double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Fatal(CultureInfo.InvariantCulture, (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1.5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Fatal("message{0}", (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", (double)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Fatal("message{0}", (decimal)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Fatal(CultureInfo.InvariantCulture, "message{0}", (decimal)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ logger.FatalException("message", new Exception("test"));
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ if (enabled == 0)
+ AssertDebugCounter("debug", 0);
+ }
+ }
+
+
+ [Test]
+ public void LogTest()
+ {
+ // test all possible overloads of the Log(level) method
+
+ foreach (LogLevel level in new LogLevel[] { LogLevel.Debug, LogLevel.Info, LogLevel.Warn, LogLevel.Error, LogLevel.Fatal })
+ {
+
+ for (int enabled = 0; enabled < 2; ++enabled)
+ {
+ XmlDocument doc = new XmlDocument();
+ if (enabled == 0)
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+ else
+ {
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' levels='" + level.Name + @"' writeTo='debug' />
+ </rules>
+ </nlog>");
+ }
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+
+ logger.Log(level, "message");
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ logger.Log(level, "message{0}", (ulong)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", (ulong)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Log(level, "message{0}", (long)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", (long)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Log(level, "message{0}", (uint)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", (uint)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Log(level, "message{0}", (int)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", (int)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Log(level, "message{0}", (ushort)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", (ushort)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Log(level, "message{0}", (sbyte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", (sbyte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Log(level, "message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", this);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageobject-to-string");
+
+ logger.Log(level, "message{0}", (short)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", (short)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Log(level, "message{0}", (byte)1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", (byte)2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2");
+
+ logger.Log(level, "message{0}", 'c');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messagec");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", 'd');
+ if (enabled == 1) AssertDebugLastMessage("debug", "messaged");
+
+ logger.Log(level, "message{0}", "ddd");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee");
+
+ logger.Log(level, "message{0}{1}", "ddd", 1);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}{1}", "eee", 2);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2");
+
+ logger.Log(level, "message{0}{1}{2}", "ddd", 1, "eee");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageddd1eee");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}{1}{2}", "eee", 2, "fff");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fff");
+
+ logger.Log(level, "message{0}{1}{2}{3}", "eee", 2, "fff", "ggg");
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageeee2fffggg");
+
+ logger.Log(level, "message{0}", true);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageTrue");
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", false);
+ if (enabled == 1) AssertDebugLastMessage("debug", "messageFalse");
+
+ CultureInfo oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Log(level, "message{0}", (float)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", (float)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Log(level, (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Log(level, CultureInfo.InvariantCulture, (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "1.5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Log(level, "message{0}", (double)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", (double)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ oldCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
+ logger.Log(level, "message{0}", (decimal)1.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message1,5");
+ System.Threading.Thread.CurrentThread.CurrentCulture = oldCulture;
+
+ logger.Log(level, CultureInfo.InvariantCulture, "message{0}", (decimal)2.5);
+ if (enabled == 1) AssertDebugLastMessage("debug", "message2.5");
+
+ logger.LogException(level, "message", new Exception("test"));
+ if (enabled == 1) AssertDebugLastMessage("debug", "message");
+
+ if (enabled == 0)
+ AssertDebugCounter("debug", 0);
+ }
+ }
+ }
+
+ public override string ToString()
+ {
+ return "object-to-string";
+ }
+
+ }
+
+
+}
diff --git a/tests/NLog.UnitTests/NLog.UnitTests.vs2003.csproj b/tests/NLog.UnitTests/NLog.UnitTests.vs2003.csproj
new file mode 100644
index 0000000..8e06287
--- /dev/null
+++ b/tests/NLog.UnitTests/NLog.UnitTests.vs2003.csproj
@@ -0,0 +1,58 @@
+<VisualStudioProject>
+ <CSHARP ProjectType="Local" ProductVersion="7.10.3077" SchemaVersion="2.0" ProjectGuid="{1653EE05-2720-4A85-BF14-74C4493787B1}">
+ <Build>
+ <Settings ApplicationIcon="" AssemblyKeyContainerName="" AssemblyName="NLog.UnitTests" AssemblyOriginatorKeyFile="" DefaultClientScript="JScript" DefaultHTMLPageLayout="Grid" DefaultTargetSchema="IE50" DelaySign="false" OutputType="Library" PreBuildEvent="" PostBuildEvent="" RootNamespace="NLog.UnitTests" RunPostBuildEvent="OnBuildSuccess" StartupObject="">
+ <Config Name="Debug" AllowUnsafeBlocks="false" BaseAddress="285212672" CheckForOverflowUnderflow="false" ConfigurationOverrideFile="" DefineConstants="DEBUG;TRACE" DocumentationFile="" DebugSymbols="true" FileAlignment="4096" IncrementalBuild="false" NoStdLib="false" NoWarn="" Optimize="false" OutputPath="bin\Debug\" RegisterForComInterop="false" RemoveIntegerChecks="false" TreatWarningsAsErrors="false" WarningLevel="4" />
+ <Config Name="Release" AllowUnsafeBlocks="false" BaseAddress="285212672" CheckForOverflowUnderflow="false" ConfigurationOverrideFile="" DefineConstants="TRACE" DocumentationFile="" DebugSymbols="false" FileAlignment="4096" IncrementalBuild="false" NoStdLib="false" NoWarn="" Optimize="true" OutputPath="bin\Release\" RegisterForComInterop="false" RemoveIntegerChecks="false" TreatWarningsAsErrors="false" WarningLevel="4" />
+ </Settings>
+ <References>
+ <Reference Name="System" AssemblyName="System" HintPath="C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll" />
+ <Reference Name="System.Data" AssemblyName="System.Data" HintPath="C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll" />
+ <Reference Name="System.XML" AssemblyName="System.Xml" HintPath="C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll" />
+ <Reference Name="nunit.framework" AssemblyName="nunit.framework" HintPath="C:\Program Files\NUnit 2.2\bin\nunit.framework.dll" AssemblyFolderKey="hklm\dn\nunit.framework" />
+ <Reference Name="NLog" Project="{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}" Package="{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" />
+ </References>
+ </Build>
+ <Files>
+ <Include>
+ <File RelPath="AssemblyInfo.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="CaseSensitivityTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="GetLoggerTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LoggerTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LogLevelTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="NLogTestBase.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="RoutingTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Filters\APITests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Filters\WhenContainsTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Filters\WhenEqualTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Filters\WhenNotContainsTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Filters\WhenNotEqualTests.cs" SubType="Code" BuildAction="Compile" />
+ <Folder RelPath="Internal\" />
+ <File RelPath="LayoutRenderers\BaseDirTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\CallSiteTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\CounterTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\DateTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\EnvironmentTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ExceptionTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\LiteralTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\LoggerNameTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\LogLevelTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\LongDateTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\MDCTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\MessageTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\NDCTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ShortDateTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\ThreadNameTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\FileTargetTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\GDCTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\ConcurrentFileTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LogManagerTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutConfigurationTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="TargetConfigurationTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="Targets\EventLogTests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\Rot13Tests.cs" SubType="Code" BuildAction="Compile" />
+ <File RelPath="LayoutRenderers\EventContextTests.cs" SubType="Code" BuildAction="Compile" />
+ </Include>
+ </Files>
+ </CSHARP>
+</VisualStudioProject>
\ No newline at end of file
diff --git a/tests/NLog.UnitTests/NLog.UnitTests.vs2005.csproj b/tests/NLog.UnitTests/NLog.UnitTests.vs2005.csproj
new file mode 100644
index 0000000..2a360d4
--- /dev/null
+++ b/tests/NLog.UnitTests/NLog.UnitTests.vs2005.csproj
@@ -0,0 +1,196 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectType>Local</ProjectType>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{1653EE05-2720-4A85-BF14-74C4493787B1}</ProjectGuid>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ApplicationIcon>
+ </ApplicationIcon>
+ <AssemblyKeyContainerName>
+ </AssemblyKeyContainerName>
+ <AssemblyName>NLog.UnitTests</AssemblyName>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <DefaultClientScript>JScript</DefaultClientScript>
+ <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+ <DefaultTargetSchema>IE50</DefaultTargetSchema>
+ <DelaySign>false</DelaySign>
+ <OutputType>Library</OutputType>
+ <RootNamespace>NLog.UnitTests</RootNamespace>
+ <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+ <StartupObject>
+ </StartupObject>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <OutputPath>bin\Debug\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DocumentationFile>
+ </DocumentationFile>
+ <DebugSymbols>true</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>
+ </NoWarn>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>4</WarningLevel>
+ <DebugType>full</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <OutputPath>bin\Release\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>TRACE</DefineConstants>
+ <DocumentationFile>
+ </DocumentationFile>
+ <DebugSymbols>false</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>
+ </NoWarn>
+ <Optimize>true</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>4</WarningLevel>
+ <DebugType>none</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="nunit.framework">
+ <Name>nunit.framework</Name>
+ <HintPath>C:\Program Files\NUnit 2.2\bin\nunit.framework.dll</HintPath>
+ <AssemblyFolderKey>hklm\dn\nunit.framework</AssemblyFolderKey>
+ </Reference>
+ <Reference Include="System">
+ <Name>System</Name>
+ </Reference>
+ <Reference Include="System.Data">
+ <Name>System.Data</Name>
+ </Reference>
+ <Reference Include="System.Xml">
+ <Name>System.XML</Name>
+ </Reference>
+ <ProjectReference Include="..\..\src\NLog\NLog.vs2005.csproj">
+ <Name>NLog.vs2005</Name>
+ <Project>{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}</Project>
+ <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AssemblyInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="CaseSensitivityTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\Rot13Tests.cs" />
+ <Compile Include="LayoutRenderers\EventContextTests.cs" />
+ <Compile Include="TargetConfigurationTests.cs" />
+ <Compile Include="LayoutConfigurationTests.cs" />
+ <Compile Include="LayoutRenderers\ExceptionTests.cs" />
+ <Compile Include="LogManagerTests.cs" />
+ <Compile Include="Filters\APITests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Filters\WhenContainsTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Filters\WhenEqualTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Filters\WhenNotContainsTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Filters\WhenNotEqualTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="GetLoggerTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\BaseDirTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\CallSiteTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\GDCTests.cs" />
+ <Compile Include="LayoutRenderers\CounterTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\DateTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\EnvironmentTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\LiteralTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\LoggerNameTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\LogLevelTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\LongDateTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\MDCTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\MessageTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\NDCTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ShortDateTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LayoutRenderers\ThreadNameTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LoggerTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LogLevelTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="NLogTestBase.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="RoutingTests.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Targets\ConcurrentFileTests.cs" />
+ <Compile Include="Targets\EventLogTests.cs" />
+ <Compile Include="Targets\FileTargetTests.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="Internal\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>
+ </PreBuildEvent>
+ <PostBuildEvent>copy /b $(ProjectDir)..\..\tools\Runner.exe $(TargetDir)</PostBuildEvent>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/tests/NLog.UnitTests/NLogTestBase.cs b/tests/NLog.UnitTests/NLogTestBase.cs
new file mode 100644
index 0000000..87f6ce7
--- /dev/null
+++ b/tests/NLog.UnitTests/NLogTestBase.cs
@@ -0,0 +1,137 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+
+using NUnit.Framework;
+using System.Text;
+using System.IO;
+using System.Diagnostics;
+using System.Threading;
+
+namespace NLog.UnitTests
+{
+ public class NLogTestBase
+ {
+ public void AssertDebugCounter(string targetName, int val)
+ {
+ NLog.Targets.DebugTarget debugTarget = (NLog.Targets.DebugTarget)LogManager.Configuration.FindTargetByName(targetName);
+
+ Assert.IsNotNull(debugTarget, "Debug target '" + targetName + "' not found");
+ Assert.AreEqual(val, debugTarget.Counter, "Unexpected counter value on '" + targetName + "'");
+ }
+
+ public void AssertDebugLastMessage(string targetName, string msg)
+ {
+ NLog.Targets.DebugTarget debugTarget = (NLog.Targets.DebugTarget)LogManager.Configuration.FindTargetByName(targetName);
+
+ // Console.WriteLine("lastmsg: {0}", debugTarget.LastMessage);
+
+ Assert.IsNotNull(debugTarget, "Debug target '" + targetName + "' not found");
+ Assert.AreEqual(msg, debugTarget.LastMessage, "Unexpected last message value on '" + targetName + "'");
+ }
+
+ public string GetDebugLastMessage(string targetName)
+ {
+ NLog.Targets.DebugTarget debugTarget = (NLog.Targets.DebugTarget)LogManager.Configuration.FindTargetByName(targetName);
+ return debugTarget.LastMessage;
+ }
+
+ public void AssertFileContents(string fileName, string contents, Encoding encoding)
+ {
+ FileInfo fi = new FileInfo(fileName);
+ if (!fi.Exists)
+ Assert.Fail("File '" + fileName + "' doesn't exist.");
+
+ byte[] encodedBuf = encoding.GetBytes(contents);
+ Assert.AreEqual(encodedBuf.Length, fi.Length, "File length is incorrect.");
+ byte[] buf = new byte[(int)fi.Length];
+ using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
+ {
+ fs.Read(buf, 0, buf.Length);
+ }
+
+ for (int i = 0; i < buf.Length; ++i)
+ {
+ Assert.AreEqual(encodedBuf[i], buf[i], "File contents are different at position: #" + i);
+ }
+ }
+
+ public string StringRepeat(int times, string s)
+ {
+ StringBuilder sb = new StringBuilder(s.Length * times);
+ for (int i = 0; i < times; ++i)
+ sb.Append(s);
+ return sb.ToString();
+ }
+
+ protected Process SpawnMethod(string methodName, params string[] p)
+ {
+ string assemblyName = this.GetType().Assembly.FullName;
+ string typename = this.GetType().FullName;
+ StringBuilder sb = new StringBuilder();
+#if MONO
+ sb.Append("Runner.exe ");
+#endif
+ sb.AppendFormat("\"{0}\" \"{1}\" \"{2}\"", assemblyName, typename, methodName);
+ foreach (string s in p)
+ {
+ sb.Append(" ");
+ sb.Append("\"");
+ sb.Append(s);
+ sb.Append("\"");
+ }
+
+ Process proc = new Process();
+ proc.StartInfo.Arguments = sb.ToString();
+#if MONO
+ proc.StartInfo.FileName = "mono";
+#else
+ proc.StartInfo.FileName = "Runner.exe";
+#endif
+ proc.StartInfo.UseShellExecute = false;
+ proc.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
+ proc.StartInfo.RedirectStandardInput = true;
+ proc.StartInfo.RedirectStandardOutput = true;
+ proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
+ proc.Start();
+ return proc;
+ }
+
+ protected void AssertLayoutRendererOutput(Layout l, string expected)
+ {
+ string actual = l.GetFormattedMessage(new LogEventInfo(LogLevel.Info, "loggername", "message"));
+ Assert.AreEqual(expected, actual);
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/RoutingTests.cs b/tests/NLog.UnitTests/RoutingTests.cs
new file mode 100644
index 0000000..72e91da
--- /dev/null
+++ b/tests/NLog.UnitTests/RoutingTests.cs
@@ -0,0 +1,191 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+
+namespace NLog.UnitTests
+{
+ [TestFixture]
+ public class RoutingTests : NLogTestBase
+ {
+ [Test]
+ public void LogThresholdTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets><target name='debug' type='Debug' layout='${message}' /></targets>
+ <rules>
+ <logger name='*' minlevel='Info' writeTo='debug' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+ logger.Debug("message");
+ AssertDebugCounter("debug", 0);
+
+ logger.Info("message");
+ AssertDebugCounter("debug", 1);
+
+ logger.Warn("message");
+ AssertDebugCounter("debug", 2);
+
+ logger.Error("message");
+ AssertDebugCounter("debug", 3);
+
+ logger.Fatal("message");
+ AssertDebugCounter("debug", 4);
+ }
+
+ [Test]
+ public void LogThresholdTest2()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets>
+ <target name='debug1' type='Debug' layout='${message}' />
+ <target name='debug2' type='Debug' layout='${message}' />
+ <target name='debug3' type='Debug' layout='${message}' />
+ <target name='debug4' type='Debug' layout='${message}' />
+ <target name='debug5' type='Debug' layout='${message}' />
+ </targets>
+ <rules>
+ <logger name='*' minlevel='Debug' writeTo='debug1' />
+ <logger name='*' minlevel='Info' writeTo='debug2' />
+ <logger name='*' minlevel='Warn' writeTo='debug3' />
+ <logger name='*' minlevel='Error' writeTo='debug4' />
+ <logger name='*' minlevel='Fatal' writeTo='debug5' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Logger logger = LogManager.GetLogger("A");
+
+ logger.Fatal("messageE");
+ logger.Error("messageD");
+ logger.Warn("messageC");
+ logger.Info("messageB");
+ logger.Debug("messageA");
+
+ AssertDebugCounter("debug1", 5);
+ AssertDebugCounter("debug2", 4);
+ AssertDebugCounter("debug3", 3);
+ AssertDebugCounter("debug4", 2);
+ AssertDebugCounter("debug5", 1);
+
+ AssertDebugLastMessage("debug1", "messageA");
+ AssertDebugLastMessage("debug2", "messageB");
+ AssertDebugLastMessage("debug3", "messageC");
+ AssertDebugLastMessage("debug4", "messageD");
+ AssertDebugLastMessage("debug5", "messageE");
+ }
+
+ [Test]
+ public void LoggerNameMatchTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets>
+ <target name='debug1' type='Debug' layout='${message}' />
+ <target name='debug2' type='Debug' layout='${message}' />
+ <target name='debug3' type='Debug' layout='${message}' />
+ <target name='debug4' type='Debug' layout='${message}' />
+ </targets>
+ <rules>
+ <logger name='A' minlevel='Info' writeTo='debug1' />
+ <logger name='A*' minlevel='Info' writeTo='debug2' />
+ <logger name='*A*' minlevel='Info' writeTo='debug3' />
+ <logger name='*A' minlevel='Info' writeTo='debug4' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ LogManager.GetLogger("A").Info("message"); // matches 1st, 2nd, 3rd and 4th rule
+ LogManager.GetLogger("A2").Info("message"); // matches 2nd rule and 3rd rule
+ LogManager.GetLogger("BAD").Info("message"); // matches 3rd rule
+ LogManager.GetLogger("BA").Info("message"); // matches 3rd and 4th rule
+
+ AssertDebugCounter("debug1", 1);
+ AssertDebugCounter("debug2", 2);
+ AssertDebugCounter("debug3", 4);
+ AssertDebugCounter("debug4", 2);
+ }
+
+ [Test]
+ public void MultiAppenderTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets>
+ <target name='debug1' type='Debug' layout='${message}' />
+ <target name='debug2' type='Debug' layout='${message}' />
+ <target name='debug3' type='Debug' layout='${message}' />
+ <target name='debug4' type='Debug' layout='${message}' />
+ </targets>
+ <rules>
+ <logger name='A' minlevel='Info' writeTo='debug1' />
+ <logger name='A' minlevel='Info' writeTo='debug2' />
+ <logger name='B' minlevel='Info' writeTo='debug1,debug2' />
+ <logger name='C' minlevel='Info' writeTo='debug1,debug2,debug3' />
+ <logger name='D' minlevel='Info' writeTo='debug1,debug2' />
+ <logger name='D' minlevel='Info' writeTo='debug3,debug4' />
+ </rules>
+ </nlog>");
+
+ LogManager.Configuration = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ LogManager.GetLogger("A").Info("message");
+ LogManager.GetLogger("B").Info("message");
+ LogManager.GetLogger("C").Info("message");
+ LogManager.GetLogger("D").Info("message");
+
+ AssertDebugCounter("debug1", 4);
+ AssertDebugCounter("debug2", 4);
+ AssertDebugCounter("debug3", 2);
+ AssertDebugCounter("debug4", 1);
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/TargetConfigurationTests.cs b/tests/NLog.UnitTests/TargetConfigurationTests.cs
new file mode 100644
index 0000000..9a67028
--- /dev/null
+++ b/tests/NLog.UnitTests/TargetConfigurationTests.cs
@@ -0,0 +1,180 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+using System.Globalization;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+using NLog.LayoutRenderers;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+using NLog.Targets.Compound;
+
+namespace NLog.UnitTests
+{
+ [TestFixture]
+ public class TargetConfigurationTests : NLogTestBase
+ {
+ [Test]
+ public void SimpleTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets>
+ <target name='d' type='Debug' layout='${message}' />
+ </targets>
+ </nlog>");
+
+ LoggingConfiguration c = new XmlLoggingConfiguration(doc.DocumentElement, null);
+ DebugTarget t = c.FindTargetByName("d") as DebugTarget;
+ Assert.IsNotNull(t);
+ Assert.AreEqual(t.Name, "d");
+ Assert.AreEqual("${message}", t.Layout);
+ Layout l = t.CompiledLayout as Layout;
+ Assert.IsNotNull(l);
+ Assert.AreEqual(1, l.Renderers.Length);
+ Assert.IsInstanceOfType(typeof(MessageLayoutRenderer), l.Renderers[0]);
+ }
+
+ [Test]
+ public void SimpleTest2()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets>
+ <target name='d' type='Debug' layout='${message:padding=10} ${level}' />
+ </targets>
+ </nlog>");
+
+ LoggingConfiguration c = new XmlLoggingConfiguration(doc.DocumentElement, null);
+ DebugTarget t = c.FindTargetByName("d") as DebugTarget;
+ Assert.IsNotNull(t);
+ Assert.AreEqual(t.Name, "d");
+ Assert.AreEqual("${message:padding=10} ${level}", t.Layout);
+ Layout l = t.CompiledLayout as Layout;
+ Assert.IsNotNull(l);
+ Assert.AreEqual(3, l.Renderers.Length);
+ Assert.IsInstanceOfType(typeof(MessageLayoutRenderer), l.Renderers[0]);
+ Assert.IsInstanceOfType(typeof(LiteralLayoutRenderer), l.Renderers[1]);
+ Assert.IsInstanceOfType(typeof(LevelLayoutRenderer), l.Renderers[2]);
+ Assert.AreEqual(10, l.Renderers[0].Padding);
+ }
+
+ [Test]
+ public void WrapperTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets>
+ <target name='b' type='BufferingWrapper' bufferSize='19'>
+ <target name='a' type='AsyncWrapper'>
+ <target name='c' type='Debug' layout='${message}' />
+ </target>
+ </target>
+ </targets>
+ </nlog>");
+
+ LoggingConfiguration c = new XmlLoggingConfiguration(doc.DocumentElement, null);
+ Assert.IsNotNull(c.FindTargetByName("a"));
+ Assert.IsNotNull(c.FindTargetByName("b"));
+ Assert.IsNotNull(c.FindTargetByName("c"));
+
+ Assert.IsInstanceOfType(typeof(BufferingTargetWrapper), c.FindTargetByName("b"));
+ Assert.IsInstanceOfType(typeof(AsyncTargetWrapper), c.FindTargetByName("a"));
+ Assert.IsInstanceOfType(typeof(DebugTarget), c.FindTargetByName("c"));
+
+ BufferingTargetWrapper btw = c.FindTargetByName("b") as BufferingTargetWrapper;
+ AsyncTargetWrapper atw = c.FindTargetByName("a") as AsyncTargetWrapper;
+ DebugTarget dt = c.FindTargetByName("c") as DebugTarget;
+
+ Assert.AreSame(atw, btw.WrappedTarget);
+ Assert.AreSame(dt, atw.WrappedTarget);
+ Assert.AreEqual(19, btw.BufferSize);
+ }
+
+ [Test]
+ public void CompoundTest()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(@"
+ <nlog>
+ <targets>
+ <target name='rr' type='RoundRobinGroup'>
+ <target name='d1' type='Debug' layout='${message}1' />
+ <target name='d2' type='Debug' layout='${message}2' />
+ <target name='d3' type='Debug' layout='${message}3' />
+ <target name='d4' type='Debug' layout='${message}4' />
+ </target>
+ </targets>
+ </nlog>");
+
+ LoggingConfiguration c = new XmlLoggingConfiguration(doc.DocumentElement, null);
+
+ Assert.IsNotNull(c.FindTargetByName("rr"));
+ Assert.IsNotNull(c.FindTargetByName("d1"));
+ Assert.IsNotNull(c.FindTargetByName("d2"));
+ Assert.IsNotNull(c.FindTargetByName("d3"));
+ Assert.IsNotNull(c.FindTargetByName("d4"));
+
+ Assert.IsInstanceOfType(typeof(RoundRobinTarget), c.FindTargetByName("rr"));
+ Assert.IsInstanceOfType(typeof(DebugTarget), c.FindTargetByName("d1"));
+ Assert.IsInstanceOfType(typeof(DebugTarget), c.FindTargetByName("d2"));
+ Assert.IsInstanceOfType(typeof(DebugTarget), c.FindTargetByName("d3"));
+ Assert.IsInstanceOfType(typeof(DebugTarget), c.FindTargetByName("d4"));
+
+ RoundRobinTarget rr = c.FindTargetByName("rr") as RoundRobinTarget;
+ DebugTarget d1 = c.FindTargetByName("d1") as DebugTarget;
+ DebugTarget d2 = c.FindTargetByName("d2") as DebugTarget;
+ DebugTarget d3 = c.FindTargetByName("d3") as DebugTarget;
+ DebugTarget d4 = c.FindTargetByName("d4") as DebugTarget;
+
+ Assert.AreEqual(4, rr.Targets.Count);
+ Assert.AreSame(d1, rr.Targets[0]);
+ Assert.AreSame(d2, rr.Targets[1]);
+ Assert.AreSame(d3, rr.Targets[2]);
+ Assert.AreSame(d4, rr.Targets[3]);
+
+ Assert.AreEqual(d1.Layout, "${message}1");
+ Assert.AreEqual(d2.Layout, "${message}2");
+ Assert.AreEqual(d3.Layout, "${message}3");
+ Assert.AreEqual(d4.Layout, "${message}4");
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/Targets/ConcurrentFileTests.cs b/tests/NLog.UnitTests/Targets/ConcurrentFileTests.cs
new file mode 100644
index 0000000..62a9384
--- /dev/null
+++ b/tests/NLog.UnitTests/Targets/ConcurrentFileTests.cs
@@ -0,0 +1,170 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+using NLog.Targets;
+using System.IO;
+using System.Text;
+using NLog.Targets.Wrappers;
+using NLog.LayoutRenderers;
+using System.Diagnostics;
+using System.Threading;
+using System.Collections;
+
+namespace NLog.UnitTests.Targets
+{
+ [TestFixture]
+ [Category("LongRunning")]
+ public class ConcurrentFileTargetTests : NLogTestBase
+ {
+ private Logger logger = LogManager.GetCurrentClassLogger();
+
+ private void ConfigureSharedFile(string mode)
+ {
+ FileTarget ft = new FileTarget();
+ ft.FileName = "${basedir}/file.txt";
+ ft.Layout = "${threadname} ${message}";
+ ft.KeepFileOpen = true;
+ ft.OpenFileCacheTimeout = 10;
+ ft.OpenFileCacheSize = 1;
+ ft.LineEnding = FileTarget.LineEndingMode.LF;
+
+ switch (mode)
+ {
+ case "async":
+ SimpleConfigurator.ConfigureForTargetLogging(new AsyncTargetWrapper(ft, 100, AsyncTargetWrapperOverflowAction.Grow), LogLevel.Debug);
+ break;
+
+ case "buffered":
+ SimpleConfigurator.ConfigureForTargetLogging(new BufferingTargetWrapper(ft, 100), LogLevel.Debug);
+ break;
+
+ case "buffered_timed_flush":
+ SimpleConfigurator.ConfigureForTargetLogging(new BufferingTargetWrapper(ft, 100, 10), LogLevel.Debug);
+ break;
+
+ default:
+ SimpleConfigurator.ConfigureForTargetLogging(ft, LogLevel.Debug);
+ break;
+ }
+ }
+
+ public void Process(string threadName, string numLogsString, string mode)
+ {
+ System.Threading.Thread.CurrentThread.Name = threadName;
+ ConfigureSharedFile(mode);
+ int numLogs = Convert.ToInt32(numLogsString);
+ for (int i = 0; i < numLogs; ++i)
+ {
+ logger.Debug("{0}", i);
+ }
+ }
+
+ private void DoConcurrentTest(int numProcesses, int numLogs, string mode)
+ {
+ string logFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "file.txt");
+
+ if (File.Exists(logFile))
+ File.Delete(logFile);
+
+ StringBuilder expectedOutput = new StringBuilder();
+
+ Process[] processes = new Process[numProcesses];
+
+ for (int i = 0; i < numProcesses; ++i)
+ {
+ processes[i] = SpawnMethod("Process", i.ToString(), numLogs.ToString(), mode);
+ }
+ for (int i = 0; i < numProcesses; ++i)
+ {
+ processes[i].WaitForExit();
+ processes[i].Dispose();
+ processes[i] = null;
+ }
+
+ int[] maxNumber = new int[numProcesses];
+
+ using (StreamReader sr = File.OpenText(logFile))
+ {
+ string line;
+
+ while ((line = sr.ReadLine()) != null)
+ {
+ string[] tokens = line.Split(' ');
+ int thread = Convert.ToInt32(tokens[0]);
+ int number = Convert.ToInt32(tokens[1]);
+
+ Assert.AreEqual(maxNumber[thread], number);
+ maxNumber[thread]++;
+ }
+ }
+ }
+
+ private void DoConcurrentTest(string mode)
+ {
+ DoConcurrentTest(2, 10000, mode);
+ DoConcurrentTest(5, 4000, mode);
+ DoConcurrentTest(10, 2000, mode);
+ }
+
+ [Test]
+ public void SimpleConcurrentTest()
+ {
+ DoConcurrentTest("");
+ }
+
+ [Test]
+ public void AsyncConcurrentTest()
+ {
+ DoConcurrentTest(2, 100, "async");
+ }
+
+ [Test]
+ public void BufferedConcurrentTest()
+ {
+ DoConcurrentTest(2, 100, "buffered");
+ }
+
+ [Test]
+ public void BufferedTimedFlushConcurrentTest()
+ {
+ DoConcurrentTest(2, 100, "buffered_timed_flush");
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/Targets/EventLogTests.cs b/tests/NLog.UnitTests/Targets/EventLogTests.cs
new file mode 100644
index 0000000..1dcd361
--- /dev/null
+++ b/tests/NLog.UnitTests/Targets/EventLogTests.cs
@@ -0,0 +1,81 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+using NLog.Targets;
+using System.IO;
+using System.Text;
+using NLog.Targets.Wrappers;
+using NLog.LayoutRenderers;
+using NLog.Win32.Targets;
+using System.Diagnostics;
+
+namespace NLog.UnitTests.Targets
+{
+ [TestFixture]
+ public class EventLogTests : NLogTestBase
+ {
+ [SetUp]
+ public void Init()
+ {
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ }
+
+ [Test]
+ [Ignore]
+ public void Test1()
+ {
+ EventLogTarget elt = new EventLogTarget();
+ elt.Log = "NLog.UnitTests";
+ elt.Source = "NLog.UnitTests";
+ elt.EventID = "10";
+ elt.Category = "123";
+ SimpleConfigurator.ConfigureForTargetLogging(elt);
+
+ LogManager.Configuration = null;
+
+ Logger l = LogManager.GetCurrentClassLogger();
+ l.Info("aaa");
+ }
+ }
+}
diff --git a/tests/NLog.UnitTests/Targets/FileTargetTests.cs b/tests/NLog.UnitTests/Targets/FileTargetTests.cs
new file mode 100644
index 0000000..95197fb
--- /dev/null
+++ b/tests/NLog.UnitTests/Targets/FileTargetTests.cs
@@ -0,0 +1,495 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.Xml;
+
+using NLog;
+using NLog.Config;
+
+using NUnit.Framework;
+using NLog.Targets;
+using System.IO;
+using System.Text;
+using NLog.Targets.Wrappers;
+using NLog.LayoutRenderers;
+
+namespace NLog.UnitTests.Targets
+{
+ [TestFixture]
+ public class FileTargetTests : NLogTestBase
+ {
+ private Logger logger = LogManager.GetCurrentClassLogger();
+
+ [Test]
+ public void SimpleFileTest1()
+ {
+ string tempFile = Path.GetTempFileName();
+ try
+ {
+ FileTarget ft = new FileTarget();
+ ft.FileName = Layout.Escape(tempFile);
+ ft.LineEnding = FileTarget.LineEndingMode.LF;
+ ft.Layout = "${level} ${message}";
+ ft.OpenFileCacheTimeout = 0;
+
+ SimpleConfigurator.ConfigureForTargetLogging(ft, LogLevel.Debug);
+
+ logger.Debug("aaa");
+ logger.Info("bbb");
+ logger.Warn("ccc");
+ LogManager.Configuration = null;
+ AssertFileContents(tempFile, "Debug aaa\nInfo bbb\nWarn ccc\n", Encoding.ASCII);
+ }
+ finally
+ {
+ if (File.Exists(tempFile))
+ File.Delete(tempFile);
+ }
+ }
+
+ [Test]
+ public void DeleteFileOnStartTest()
+ {
+ string tempFile = Path.GetTempFileName();
+ try
+ {
+ FileTarget ft = new FileTarget();
+ ft.FileName = Layout.Escape(tempFile);
+ ft.LineEnding = FileTarget.LineEndingMode.LF;
+ ft.Layout = "${level} ${message}";
+
+ SimpleConfigurator.ConfigureForTargetLogging(ft, LogLevel.Debug);
+
+ logger.Debug("aaa");
+ logger.Info("bbb");
+ logger.Warn("ccc");
+
+ LogManager.Configuration = null;
+
+ AssertFileContents(tempFile, "Debug aaa\nInfo bbb\nWarn ccc\n", Encoding.ASCII);
+
+ // configure again, without
+ // DeleteOldFileOnStartup
+
+ ft = new FileTarget();
+ ft.FileName = Layout.Escape(tempFile);
+ ft.LineEnding = FileTarget.LineEndingMode.LF;
+ ft.Layout = "${level} ${message}";
+
+ SimpleConfigurator.ConfigureForTargetLogging(ft, LogLevel.Debug);
+
+ logger.Debug("aaa");
+ logger.Info("bbb");
+ logger.Warn("ccc");
+
+ LogManager.Configuration = null;
+ AssertFileContents(tempFile, "Debug aaa\nInfo bbb\nWarn ccc\nDebug aaa\nInfo bbb\nWarn ccc\n", Encoding.ASCII);
+
+ // configure again, this time with
+ // DeleteOldFileOnStartup
+
+ ft = new FileTarget();
+ ft.FileName = Layout.Escape(tempFile);
+ ft.LineEnding = FileTarget.LineEndingMode.LF;
+ ft.Layout = "${level} ${message}";
+ ft.DeleteOldFileOnStartup = true;
+
+ SimpleConfigurator.ConfigureForTargetLogging(ft, LogLevel.Debug);
+ logger.Debug("aaa");
+ logger.Info("bbb");
+ logger.Warn("ccc");
+
+ LogManager.Configuration = null;
+ AssertFileContents(tempFile, "Debug aaa\nInfo bbb\nWarn ccc\n", Encoding.ASCII);
+ }
+ finally
+ {
+ LogManager.Configuration = null;
+ if (File.Exists(tempFile))
+ File.Delete(tempFile);
+ }
+ }
+
+ [Test]
+ public void CreateDirsTest()
+ {
+ // create the file in a not-existent
+ // directory which forces creation
+ string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
+ string tempFile = Path.Combine(tempPath, "file.txt");
+ try
+ {
+ FileTarget ft = new FileTarget();
+ ft.FileName = tempFile;
+ ft.LineEnding = FileTarget.LineEndingMode.LF;
+ ft.Layout = "${level} ${message}";
+
+ SimpleConfigurator.ConfigureForTargetLogging(ft, LogLevel.Debug);
+
+ logger.Debug("aaa");
+ logger.Info("bbb");
+ logger.Warn("ccc");
+ LogManager.Configuration = null;
+ AssertFileContents(tempFile, "Debug aaa\nInfo bbb\nWarn ccc\n", Encoding.ASCII);
+ }
+ finally
+ {
+ LogManager.Configuration = null;
+ if (File.Exists(tempFile))
+ File.Delete(tempFile);
+ if (Directory.Exists(tempPath))
+ Directory.Delete(tempPath, true);
+ }
+ }
+
+ [Test]
+ public void SequentialArchiveTest1()
+ {
+ // create the file in a not-existent
+ // directory which forces creation
+ string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
+ string tempFile = Path.Combine(tempPath, "file.txt");
+ try
+ {
+ FileTarget ft = new FileTarget();
+ ft.FileName = tempFile;
+ ft.ArchiveFileName = Path.Combine(tempPath, "archive/{####}.txt");
+ ft.ArchiveAboveSize = 1000;
+ ft.LineEnding = FileTarget.LineEndingMode.LF;
+ ft.Layout = "${message}";
+ ft.MaxArchiveFiles = 3;
+ ft.ArchiveNumbering = FileTarget.ArchiveNumberingMode.Sequence;
+
+ SimpleConfigurator.ConfigureForTargetLogging(ft, LogLevel.Debug);
+
+ // we emit 5 * 250 *(3 x aaa + \n) bytes
+ // so that we should get a full file + 3 archives
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Debug("aaa");
+ }
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Debug("bbb");
+ }
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Debug("ccc");
+ }
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Debug("ddd");
+ }
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Debug("eee");
+ }
+
+ LogManager.Configuration = null;
+
+ AssertFileContents(tempFile,
+ StringRepeat(250, "eee\n"),
+ Encoding.ASCII);
+
+ AssertFileContents(
+ Path.Combine(tempPath, "archive/0001.txt"),
+ StringRepeat(250, "bbb\n"),
+ Encoding.ASCII);
+
+ AssertFileContents(
+ Path.Combine(tempPath, "archive/0002.txt"),
+ StringRepeat(250, "ccc\n"),
+ Encoding.ASCII);
+
+ AssertFileContents(
+ Path.Combine(tempPath, "archive/0003.txt"),
+ StringRepeat(250, "ddd\n"),
+ Encoding.ASCII);
+
+ Assert.IsTrue(!File.Exists(Path.Combine(tempPath, "archive/0000.txt")));
+ Assert.IsTrue(!File.Exists(Path.Combine(tempPath, "archive/0004.txt")));
+ }
+ finally
+ {
+ LogManager.Configuration = null;
+ if (File.Exists(tempFile))
+ File.Delete(tempFile);
+ if (Directory.Exists(tempPath))
+ Directory.Delete(tempPath, true);
+ }
+ }
+
+ [Test]
+ public void RollingArchiveTest1()
+ {
+ // create the file in a not-existent
+ // directory which forces creation
+ string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
+ string tempFile = Path.Combine(tempPath, "file.txt");
+ try
+ {
+ FileTarget ft = new FileTarget();
+ ft.FileName = tempFile;
+ ft.ArchiveFileName = Path.Combine(tempPath, "archive/{####}.txt");
+ ft.ArchiveAboveSize = 1000;
+ ft.LineEnding = FileTarget.LineEndingMode.LF;
+ ft.ArchiveNumbering = FileTarget.ArchiveNumberingMode.Rolling;
+ ft.Layout = "${message}";
+ ft.MaxArchiveFiles = 3;
+
+ SimpleConfigurator.ConfigureForTargetLogging(ft, LogLevel.Debug);
+
+ // we emit 5 * 250 * (3 x aaa + \n) bytes
+ // so that we should get a full file + 3 archives
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Debug("aaa");
+ }
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Debug("bbb");
+ }
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Debug("ccc");
+ }
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Debug("ddd");
+ }
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Debug("eee");
+ }
+
+ LogManager.Configuration = null;
+
+ AssertFileContents(tempFile,
+ StringRepeat(250, "eee\n"),
+ Encoding.ASCII);
+
+ AssertFileContents(
+ Path.Combine(tempPath, "archive/0000.txt"),
+ StringRepeat(250, "ddd\n"),
+ Encoding.ASCII);
+
+ AssertFileContents(
+ Path.Combine(tempPath, "archive/0001.txt"),
+ StringRepeat(250, "ccc\n"),
+ Encoding.ASCII);
+
+ AssertFileContents(
+ Path.Combine(tempPath, "archive/0002.txt"),
+ StringRepeat(250, "bbb\n"),
+ Encoding.ASCII);
+
+ Assert.IsTrue(!File.Exists(Path.Combine(tempPath, "archive/0003.txt")));
+ }
+ finally
+ {
+ LogManager.Configuration = null;
+ if (File.Exists(tempFile))
+ File.Delete(tempFile);
+ if (Directory.Exists(tempPath))
+ Directory.Delete(tempPath, true);
+ }
+ }
+
+ [Test]
+ public void MultiFileWrite()
+ {
+ // create the file in a not-existent
+ // directory which forces creation
+ string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
+ try
+ {
+ FileTarget ft = new FileTarget();
+ ft.FileName = Path.Combine(tempPath, "${level}.txt");
+ ft.LineEnding = FileTarget.LineEndingMode.LF;
+ ft.Layout = "${message}";
+
+ SimpleConfigurator.ConfigureForTargetLogging(ft, LogLevel.Debug);
+
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Trace("@@@");
+ logger.Debug("aaa");
+ logger.Info("bbb");
+ logger.Warn("ccc");
+ logger.Error("ddd");
+ logger.Fatal("eee");
+ }
+
+ LogManager.Configuration = null;
+
+ Assert.IsFalse(File.Exists(Path.Combine(tempPath, "Trace.txt")));
+
+ AssertFileContents(Path.Combine(tempPath, "Debug.txt"),
+ StringRepeat(250, "aaa\n"), Encoding.ASCII);
+
+ AssertFileContents(Path.Combine(tempPath, "Info.txt"),
+ StringRepeat(250, "bbb\n"), Encoding.ASCII);
+
+ AssertFileContents(Path.Combine(tempPath, "Warn.txt"),
+ StringRepeat(250, "ccc\n"), Encoding.ASCII);
+
+ AssertFileContents(Path.Combine(tempPath, "Error.txt"),
+ StringRepeat(250, "ddd\n"), Encoding.ASCII);
+
+ AssertFileContents(Path.Combine(tempPath, "Fatal.txt"),
+ StringRepeat(250, "eee\n"), Encoding.ASCII);
+ }
+ finally
+ {
+ //if (File.Exists(tempFile))
+ // File.Delete(tempFile);
+ LogManager.Configuration = null;
+ if (Directory.Exists(tempPath))
+ Directory.Delete(tempPath, true);
+ }
+ }
+
+ [Test]
+ public void BufferedMultiFileWrite()
+ {
+ // create the file in a not-existent
+ // directory which forces creation
+ string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
+ try
+ {
+ FileTarget ft = new FileTarget();
+ ft.FileName = Path.Combine(tempPath, "${level}.txt");
+ ft.LineEnding = FileTarget.LineEndingMode.LF;
+ ft.Layout = "${message}";
+
+ SimpleConfigurator.ConfigureForTargetLogging(new BufferingTargetWrapper(ft,10), LogLevel.Debug);
+
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Trace("@@@");
+ logger.Debug("aaa");
+ logger.Info("bbb");
+ logger.Warn("ccc");
+ logger.Error("ddd");
+ logger.Fatal("eee");
+ }
+
+ LogManager.Configuration = null;
+
+ Assert.IsFalse(File.Exists(Path.Combine(tempPath, "Trace.txt")));
+
+ AssertFileContents(Path.Combine(tempPath, "Debug.txt"),
+ StringRepeat(250, "aaa\n"), Encoding.ASCII);
+
+ AssertFileContents(Path.Combine(tempPath, "Info.txt"),
+ StringRepeat(250, "bbb\n"), Encoding.ASCII);
+
+ AssertFileContents(Path.Combine(tempPath, "Warn.txt"),
+ StringRepeat(250, "ccc\n"), Encoding.ASCII);
+
+ AssertFileContents(Path.Combine(tempPath, "Error.txt"),
+ StringRepeat(250, "ddd\n"), Encoding.ASCII);
+
+ AssertFileContents(Path.Combine(tempPath, "Fatal.txt"),
+ StringRepeat(250, "eee\n"), Encoding.ASCII);
+ }
+ finally
+ {
+ //if (File.Exists(tempFile))
+ // File.Delete(tempFile);
+ LogManager.Configuration = null;
+ if (Directory.Exists(tempPath))
+ Directory.Delete(tempPath, true);
+ }
+ }
+
+ [Test]
+ public void AsyncMultiFileWrite()
+ {
+ string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
+ try
+ {
+ FileTarget ft = new FileTarget();
+ ft.FileName = Path.Combine(tempPath, "${level}.txt");
+ ft.LineEnding = FileTarget.LineEndingMode.LF;
+ ft.Layout = "${message} ${threadid}";
+
+ // this also checks that thread-volatile layouts
+ // such as ${threadid} are properly cached and not recalculated
+ // in logging threads.
+
+ string threadID = NLog.Internal.ThreadIDHelper.Instance.CurrentThreadID.ToString();
+
+ SimpleConfigurator.ConfigureForTargetLogging(new AsyncTargetWrapper(ft, 1000, AsyncTargetWrapperOverflowAction.Grow), LogLevel.Debug);
+
+ for (int i = 0; i < 250; ++i)
+ {
+ logger.Trace("@@@");
+ logger.Debug("aaa");
+ logger.Info("bbb");
+ logger.Warn("ccc");
+ logger.Error("ddd");
+ logger.Fatal("eee");
+ }
+
+ LogManager.Configuration = null;
+
+ Assert.IsFalse(File.Exists(Path.Combine(tempPath, "Trace.txt")));
+
+ AssertFileContents(Path.Combine(tempPath, "Debug.txt"),
+ StringRepeat(250, "aaa " + threadID +"\n"), Encoding.ASCII);
+
+ AssertFileContents(Path.Combine(tempPath, "Info.txt"),
+ StringRepeat(250, "bbb " + threadID + "\n"), Encoding.ASCII);
+
+ AssertFileContents(Path.Combine(tempPath, "Warn.txt"),
+ StringRepeat(250, "ccc " + threadID + "\n"), Encoding.ASCII);
+
+ AssertFileContents(Path.Combine(tempPath, "Error.txt"),
+ StringRepeat(250, "ddd " + threadID + "\n"), Encoding.ASCII);
+
+ AssertFileContents(Path.Combine(tempPath, "Fatal.txt"),
+ StringRepeat(250, "eee " + threadID + "\n"), Encoding.ASCII);
+ }
+ finally
+ {
+ //if (File.Exists(tempFile))
+ // File.Delete(tempFile);
+ LogManager.Configuration = null;
+ if (Directory.Exists(tempPath))
+ Directory.Delete(tempPath, true);
+ }
+ }
+ }
+}
diff --git a/tests/NLog.VBTest/App.config b/tests/NLog.VBTest/App.config
new file mode 100644
index 0000000..b01e944
--- /dev/null
+++ b/tests/NLog.VBTest/App.config
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<configuration>
+ <configSections>
+ <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
+ </configSections>
+ <nlog autoReload="true">
+ <targets>
+ <target name="console" type="Console" layout="${longdate}|${logger}|${level}|${message}" />
+ <target name="file" type="File" filename="${basedir}/log.txt" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" appendTo="console,file" />
+ </rules>
+ </nlog>
+</configuration>
+
diff --git a/tests/NLog.VBTest/AssemblyInfo.vb b/tests/NLog.VBTest/AssemblyInfo.vb
new file mode 100644
index 0000000..54c0ec5
--- /dev/null
+++ b/tests/NLog.VBTest/AssemblyInfo.vb
@@ -0,0 +1,32 @@
+Imports System
+Imports System.Reflection
+Imports System.Runtime.InteropServices
+
+' General Information about an assembly is controlled through the following
+' set of attributes. Change these attribute values to modify the information
+' associated with an assembly.
+
+' Review the values of the assembly attributes
+
+<Assembly: AssemblyTitle("")>
+<Assembly: AssemblyDescription("")>
+<Assembly: AssemblyCompany("")>
+<Assembly: AssemblyProduct("")>
+<Assembly: AssemblyCopyright("")>
+<Assembly: AssemblyTrademark("")>
+<Assembly: CLSCompliant(True)>
+
+'The following GUID is for the ID of the typelib if this project is exposed to COM
+<Assembly: Guid("81B4540F-24B5-4155-B97B-C9C91A107752")>
+
+' Version information for an assembly consists of the following four values:
+'
+' Major Version
+' Minor Version
+' Build Number
+' Revision
+'
+' You can specify all the values or you can default the Build and Revision Numbers
+' by using the '*' as shown below:
+
+<Assembly: AssemblyVersion("1.0.*")>
diff --git a/tests/NLog.VBTest/Module1.vb b/tests/NLog.VBTest/Module1.vb
new file mode 100644
index 0000000..3a76124
--- /dev/null
+++ b/tests/NLog.VBTest/Module1.vb
@@ -0,0 +1,6 @@
+Module Module1
+ Dim logger As NLog.Logger = LogManager.GetLogger("Logger1")
+ Sub Main()
+ logger.Debug("Hello {0}", "world!")
+ End Sub
+End Module
diff --git a/tests/NLog.VBTest/NLog.VBTest-net-2.0.vbproj b/tests/NLog.VBTest/NLog.VBTest-net-2.0.vbproj
new file mode 100644
index 0000000..a987073
--- /dev/null
+++ b/tests/NLog.VBTest/NLog.VBTest-net-2.0.vbproj
@@ -0,0 +1,113 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectType>Local</ProjectType>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{2993B4C3-A0EE-43C8-84EB-97920E69B292}</ProjectGuid>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ApplicationIcon>
+ </ApplicationIcon>
+ <AssemblyKeyContainerName>
+ </AssemblyKeyContainerName>
+ <AssemblyName>NLog.VBTest</AssemblyName>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <AssemblyOriginatorKeyMode>None</AssemblyOriginatorKeyMode>
+ <DefaultClientScript>JScript</DefaultClientScript>
+ <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+ <DefaultTargetSchema>IE50</DefaultTargetSchema>
+ <DelaySign>false</DelaySign>
+ <OutputType>Exe</OutputType>
+ <OptionCompare>Binary</OptionCompare>
+ <OptionExplicit>On</OptionExplicit>
+ <OptionStrict>Off</OptionStrict>
+ <RootNamespace>NLog.VBTest</RootNamespace>
+ <StartupObject>NLog.VBTest.Module1</StartupObject>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <MyType>Console</MyType>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <OutputPath>bin\</OutputPath>
+ <DocumentationFile>NLog.VBTest.xml</DocumentationFile>
+ <BaseAddress>285212672</BaseAddress>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>
+ </DefineConstants>
+ <DefineDebug>true</DefineDebug>
+ <DefineTrace>true</DefineTrace>
+ <DebugSymbols>true</DebugSymbols>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>1</WarningLevel>
+ <NoWarn>42016,42017,42018,42019,42032</NoWarn>
+ <DebugType>full</DebugType>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <OutputPath>bin\</OutputPath>
+ <DocumentationFile>NLog.VBTest.xml</DocumentationFile>
+ <BaseAddress>285212672</BaseAddress>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>
+ </DefineConstants>
+ <DefineDebug>false</DefineDebug>
+ <DefineTrace>true</DefineTrace>
+ <DebugSymbols>false</DebugSymbols>
+ <Optimize>true</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>1</WarningLevel>
+ <NoWarn>42016,42017,42018,42019,42032</NoWarn>
+ <DebugType>none</DebugType>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System">
+ <Name>System</Name>
+ </Reference>
+ <Reference Include="System.Data">
+ <Name>System.Data</Name>
+ </Reference>
+ <Reference Include="System.Xml">
+ <Name>System.XML</Name>
+ </Reference>
+ <ProjectReference Include="..\..\src\NLog\NLog-net-2.0.csproj">
+ <Name>NLog-net-2.0</Name>
+ <Project>{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}</Project>
+ <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Import Include="Microsoft.VisualBasic" />
+ <Import Include="System" />
+ <Import Include="System.Collections" />
+ <Import Include="System.Data" />
+ <Import Include="System.Diagnostics" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ <Compile Include="AssemblyInfo.vb">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Module1.vb">
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="My Project\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>
+ </PreBuildEvent>
+ <PostBuildEvent>
+ </PostBuildEvent>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/tests/NLog.VBTest/NLog.VBTest.vs2003.vbproj b/tests/NLog.VBTest/NLog.VBTest.vs2003.vbproj
new file mode 100644
index 0000000..3e4cb13
--- /dev/null
+++ b/tests/NLog.VBTest/NLog.VBTest.vs2003.vbproj
@@ -0,0 +1,106 @@
+<VisualStudioProject>
+ <VisualBasic
+ ProjectType = "Local"
+ ProductVersion = "7.10.3077"
+ SchemaVersion = "2.0"
+ ProjectGuid = "{2993B4C3-A0EE-43C8-84EB-97920E69B292}"
+ >
+ <Build>
+ <Settings
+ ApplicationIcon = ""
+ AssemblyKeyContainerName = ""
+ AssemblyName = "NLog.VBTest"
+ AssemblyOriginatorKeyFile = ""
+ AssemblyOriginatorKeyMode = "None"
+ DefaultClientScript = "JScript"
+ DefaultHTMLPageLayout = "Grid"
+ DefaultTargetSchema = "IE50"
+ DelaySign = "false"
+ OutputType = "Exe"
+ OptionCompare = "Binary"
+ OptionExplicit = "On"
+ OptionStrict = "Off"
+ RootNamespace = "NLog.VBTest"
+ StartupObject = "NLog.VBTest.Module1"
+ >
+ <Config
+ Name = "Debug"
+ BaseAddress = "285212672"
+ ConfigurationOverrideFile = ""
+ DefineConstants = ""
+ DefineDebug = "true"
+ DefineTrace = "true"
+ DebugSymbols = "true"
+ IncrementalBuild = "true"
+ Optimize = "false"
+ OutputPath = "bin\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "1"
+ />
+ <Config
+ Name = "Release"
+ BaseAddress = "285212672"
+ ConfigurationOverrideFile = ""
+ DefineConstants = ""
+ DefineDebug = "false"
+ DefineTrace = "true"
+ DebugSymbols = "false"
+ IncrementalBuild = "false"
+ Optimize = "true"
+ OutputPath = "bin\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "1"
+ />
+ </Settings>
+ <References>
+ <Reference
+ Name = "System"
+ AssemblyName = "System"
+ />
+ <Reference
+ Name = "System.Data"
+ AssemblyName = "System.Data"
+ />
+ <Reference
+ Name = "System.XML"
+ AssemblyName = "System.Xml"
+ />
+ <Reference
+ Name = "NLog"
+ Project = "{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+ Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+ />
+ </References>
+ <Imports>
+ <Import Namespace = "Microsoft.VisualBasic" />
+ <Import Namespace = "System" />
+ <Import Namespace = "System.Collections" />
+ <Import Namespace = "System.Data" />
+ <Import Namespace = "System.Diagnostics" />
+ </Imports>
+ </Build>
+ <Files>
+ <Include>
+ <File
+ RelPath = "App.config"
+ BuildAction = "None"
+ />
+ <File
+ RelPath = "AssemblyInfo.vb"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Module1.vb"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ </Include>
+ </Files>
+ </VisualBasic>
+</VisualStudioProject>
+
diff --git a/tests/NLogCTest/AssemblyInfo.cpp b/tests/NLogCTest/AssemblyInfo.cpp
new file mode 100644
index 0000000..3279e45
--- /dev/null
+++ b/tests/NLogCTest/AssemblyInfo.cpp
@@ -0,0 +1,60 @@
+#include "stdafx.h"
+
+#using <mscorlib.dll>
+
+using namespace System::Reflection;
+using namespace System::Runtime::CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly:AssemblyTitleAttribute("")];
+[assembly:AssemblyDescriptionAttribute("")];
+[assembly:AssemblyConfigurationAttribute("")];
+[assembly:AssemblyCompanyAttribute("")];
+[assembly:AssemblyProductAttribute("")];
+[assembly:AssemblyCopyrightAttribute("")];
+[assembly:AssemblyTrademarkAttribute("")];
+[assembly:AssemblyCultureAttribute("")];
+
+//
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the value or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly:AssemblyVersionAttribute("1.0.*")];
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+// (*) If no key is specified, the assembly is not signed.
+// (*) KeyName refers to a key that has been installed in the Crypto Service
+// Provider (CSP) on your machine. KeyFile refers to a file which contains
+// a key.
+// (*) If the KeyFile and the KeyName values are both specified, the
+// following processing occurs:
+// (1) If the KeyName can be found in the CSP, that key is used.
+// (2) If the KeyName does not exist and the KeyFile does exist, the key
+// in the KeyFile is installed into the CSP and used.
+// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+// When specifying the KeyFile, the location of the KeyFile should be
+// relative to the project directory.
+// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+// documentation for more information on this.
+//
+[assembly:AssemblyDelaySignAttribute(false)];
+[assembly:AssemblyKeyFileAttribute("")];
+[assembly:AssemblyKeyNameAttribute("")];
+
diff --git a/tests/NLogCTest/NLogCTest.cpp b/tests/NLogCTest/NLogCTest.cpp
new file mode 100644
index 0000000..466ca7c
--- /dev/null
+++ b/tests/NLogCTest/NLogCTest.cpp
@@ -0,0 +1,77 @@
+#include "stdafx.h"
+
+#include "NLogC.h"
+
+int main()
+{
+ NLog_InitLocal();
+ NLog_ConfigureFromFile("config.nlog");
+ int repeatCount = 500000;
+ int t0, t1;
+
+ t0 = GetTickCount();
+ for (int i = 0; i < repeatCount; ++i)
+ {
+ NLog_DebugA("nnn", "message");
+ }
+ t1 = GetTickCount();
+ printf("ANSI: %f nanoseconds per null-log\n", (t1 - t0) * 1000000.0 / repeatCount);
+
+ t0 = GetTickCount();
+ for (int i = 0; i < repeatCount; ++i)
+ {
+ NLog_DebugA("nnn", "message with %s", "sprintf() formatting");
+ }
+ t1 = GetTickCount();
+ printf("ANSI: %f nanoseconds per null-log with sprintf() formatting\n", (t1 - t0) * 1000000.0 / repeatCount);
+
+ t0 = GetTickCount();
+ for (int i = 0; i < repeatCount; ++i)
+ {
+ NLog_DebugA("rrr", "message");
+ }
+ t1 = GetTickCount();
+ printf("ANSI: %f nanoseconds per non-logging\n", (t1 - t0) * 1000000.0 / repeatCount);
+
+ t0 = GetTickCount();
+ for (int i = 0; i < repeatCount; ++i)
+ {
+ NLog_DebugA("rrr", "message with %s", "stringf() formatting");
+ }
+ t1 = GetTickCount();
+ printf("ANSI: %f nanoseconds per non-logging with sprintf() formatting\n", (t1 - t0) * 1000000.0 / repeatCount);
+
+ t0 = GetTickCount();
+ for (int i = 0; i < repeatCount; ++i)
+ {
+ NLog_DebugW(L"nnn", L"message");
+ }
+ t1 = GetTickCount();
+ printf("UNICODE: %f nanoseconds per null-log\n", (t1 - t0) * 1000000.0 / repeatCount);
+
+ t0 = GetTickCount();
+ for (int i = 0; i < repeatCount; ++i)
+ {
+ NLog_DebugW(L"nnn", L"message with %s", L"stringf() formatting");
+ }
+ t1 = GetTickCount();
+ printf("UNICODE: %f nanoseconds per null-logging with sprintf() formatting\n", (t1 - t0) * 1000000.0 / repeatCount);
+
+ t0 = GetTickCount();
+ for (int i = 0; i < repeatCount; ++i)
+ {
+ NLog_DebugW(L"rrr", L"message");
+ }
+ t1 = GetTickCount();
+ printf("UNICODE: %f nanoseconds per non-logging\n", (t1 - t0) * 1000000.0 / repeatCount);
+
+ t0 = GetTickCount();
+ for (int i = 0; i < repeatCount; ++i)
+ {
+ NLog_DebugW(L"rrr", L"message with %s", L"stringf() formatting");
+ }
+ t1 = GetTickCount();
+ printf("UNICODE: %f nanoseconds per non-logging with sprintf() formatting\n", (t1 - t0) * 1000000.0 / repeatCount);
+
+ return 0;
+}
\ No newline at end of file
diff --git a/tests/NLogCTest/NLogCTest.vs2003.vcproj b/tests/NLogCTest/NLogCTest.vs2003.vcproj
new file mode 100644
index 0000000..a770129
--- /dev/null
+++ b/tests/NLogCTest/NLogCTest.vs2003.vcproj
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="NLogCTest.vs2003"
+ ProjectGUID="{3A3B8573-0A64-414D-9E8D-9F1982004299}"
+ RootNamespace="NLogCTest"
+ Keyword="ManagedCProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ProjectDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ ManagedExtensions="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\src\NLogC"
+ PreprocessorDefinitions="WIN32;_DEBUG"
+ MinimalRebuild="FALSE"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="copy /b $(ProjectDir)..\..\src\NLogC\$(ConfigurationName)\NLogC.dll $(OutDir)
+copy /b $(ProjectDir)..\..\src\NLog\bin\$(ConfigurationName)\NLog.dll $(OutDir)
+copy /b $(ProjectDir)config.nlog $(TargetPath).nlog
+"
+ Outputs="$(OutDir)\NLog.dll"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="NLogC.lib"
+ OutputFile="$(OutDir)\$(ProjectName).exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""..\..\src\NLogC\$(ConfigurationName)""
+ GenerateDebugInformation="TRUE"
+ AssemblyDebug="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ProjectDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ ManagedExtensions="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\src\NLogC"
+ PreprocessorDefinitions="WIN32;NDEBUG"
+ MinimalRebuild="FALSE"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="copy /b $(ProjectDir)..\..\src\NLogC\$(ConfigurationName)\NLogC.dll $(OutDir)
+copy /b $(ProjectDir)..\..\src\NLog\bin\$(ConfigurationName)\NLog.dll $(OutDir)
+copy /b $(ProjectDir)config.nlog $(TargetPath).nlog
+"
+ Outputs="$(OutDir)\NLog.dll"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="NLogC.lib"
+ OutputFile="$(OutDir)\$(ProjectName).exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""..\..\src\NLogC\$(ConfigurationName)""
+ GenerateDebugInformation="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ <ProjectReference
+ ReferencedProjectIdentifier="{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+ Name="NLog"/>
+ <ProjectReference
+ ReferencedProjectIdentifier="{63966F8B-B3DA-4538-AF36-FCBBFFF67BF7}"
+ Name="NLogC"/>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\NLogCTest.cpp">
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\resource.h">
+ </File>
+ <File
+ RelativePath=".\stdafx.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ <File
+ RelativePath=".\app.ico">
+ </File>
+ <File
+ RelativePath=".\app.rc">
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\config.nlog">
+ </File>
+ <File
+ RelativePath=".\ReadMe.txt">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/tests/NLogCTest/ReadMe.txt b/tests/NLogCTest/ReadMe.txt
new file mode 100644
index 0000000..f140bdf
--- /dev/null
+++ b/tests/NLogCTest/ReadMe.txt
@@ -0,0 +1,28 @@
+========================================================================
+ APPLICATION : NLogCTest Project Overview
+========================================================================
+
+AppWizard has created this NLogCTest Application for you.
+
+This file contains a summary of what you will find in each of the files that
+make up your NLogCTest application.
+
+NLogCTest.vcproj
+ This is the main project file for VC++ projects generated using an Application Wizard.
+ It contains information about the version of Visual C++ that generated the file, and
+ information about the platforms, configurations, and project features selected with the
+ Application Wizard.
+
+NLogCTest.cpp
+ This is the main application source file.
+
+AssemblyInfo.cpp
+ Contains custom attributes for modifying assembly metadata.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/tests/NLogCTest/app.ico b/tests/NLogCTest/app.ico
new file mode 100644
index 0000000..3a5525f
Binary files /dev/null and b/tests/NLogCTest/app.ico differ
diff --git a/tests/NLogCTest/app.rc b/tests/NLogCTest/app.rc
new file mode 100644
index 0000000..b488dbd
--- /dev/null
+++ b/tests/NLogCTest/app.rc
@@ -0,0 +1,52 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon placed first or with lowest ID value becomes application icon
+
+LANGUAGE 9, 1
+#pragma code_page(1252)
+1 ICON "app.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/tests/NLogCTest/config.nlog b/tests/NLogCTest/config.nlog
new file mode 100644
index 0000000..a44ff2c
--- /dev/null
+++ b/tests/NLogCTest/config.nlog
@@ -0,0 +1,11 @@
+<nlog>
+ <appenders>
+ <appender name="console" type="Console" />
+ <appender name="null" type="Null" />
+ </appenders>
+
+ <rules>
+ <logger name="kkk" appendTo="console" />
+ <logger name="nnn" appendTo="null" />
+ </rules>
+</nlog>
diff --git a/tests/NLogCTest/resource.h b/tests/NLogCTest/resource.h
new file mode 100644
index 0000000..1f2251c
--- /dev/null
+++ b/tests/NLogCTest/resource.h
@@ -0,0 +1,3 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by app.rc
diff --git a/tests/NLogCTest/stdafx.cpp b/tests/NLogCTest/stdafx.cpp
new file mode 100644
index 0000000..df8d3dc
--- /dev/null
+++ b/tests/NLogCTest/stdafx.cpp
@@ -0,0 +1,7 @@
+// stdafx.cpp : source file that includes just the standard includes
+// NLogCTest.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
diff --git a/tests/NLogCTest/stdafx.h b/tests/NLogCTest/stdafx.h
new file mode 100644
index 0000000..322660e
--- /dev/null
+++ b/tests/NLogCTest/stdafx.h
@@ -0,0 +1,11 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#include <iostream>
+#include <tchar.h>
+
+#include <windows.h>
+
+// TODO: reference additional headers your program requires here
diff --git a/tests/NLogTests.vs2003.sln b/tests/NLogTests.vs2003.sln
new file mode 100644
index 0000000..350f614
--- /dev/null
+++ b/tests/NLogTests.vs2003.sln
@@ -0,0 +1,53 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.Test.vs2003", "NLog.Test\NLog.Test.vs2003.csproj", "{5EC49108-97AE-40EA-B550-8960E4522718}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.vs2003", "..\src\NLog\NLog.vs2003.csproj", "{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.AsyncBenchmark.vs2003", "NLog.AsyncBenchmark\NLog.AsyncBenchmark.vs2003.csproj", "{F666E83B-3806-4F90-A577-809AA8EEED0E}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.UnitTests.vs2003", "NLog.UnitTests\NLog.UnitTests.vs2003.csproj", "{1653EE05-2720-4A85-BF14-74C4493787B1}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.Benchmark.vs2003", "NLog.Benchmark\NLog.Benchmark.vs2003.csproj", "{842A5DA9-BA2B-4934-8ED6-2E6495F7476D}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Debug.ActiveCfg = Debug|.NET
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Debug.Build.0 = Debug|.NET
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Release.ActiveCfg = Release|.NET
+ {5EC49108-97AE-40EA-B550-8960E4522718}.Release.Build.0 = Release|.NET
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug.ActiveCfg = Debug|.NET
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug.Build.0 = Debug|.NET
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release.ActiveCfg = Release|.NET
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release.Build.0 = Release|.NET
+ {F666E83B-3806-4F90-A577-809AA8EEED0E}.Debug.ActiveCfg = Debug|.NET
+ {F666E83B-3806-4F90-A577-809AA8EEED0E}.Debug.Build.0 = Debug|.NET
+ {F666E83B-3806-4F90-A577-809AA8EEED0E}.Release.ActiveCfg = Release|.NET
+ {F666E83B-3806-4F90-A577-809AA8EEED0E}.Release.Build.0 = Release|.NET
+ {1653EE05-2720-4A85-BF14-74C4493787B1}.Debug.ActiveCfg = Debug|.NET
+ {1653EE05-2720-4A85-BF14-74C4493787B1}.Debug.Build.0 = Debug|.NET
+ {1653EE05-2720-4A85-BF14-74C4493787B1}.Release.ActiveCfg = Release|.NET
+ {1653EE05-2720-4A85-BF14-74C4493787B1}.Release.Build.0 = Release|.NET
+ {842A5DA9-BA2B-4934-8ED6-2E6495F7476D}.Debug.ActiveCfg = Debug|.NET
+ {842A5DA9-BA2B-4934-8ED6-2E6495F7476D}.Debug.Build.0 = Debug|.NET
+ {842A5DA9-BA2B-4934-8ED6-2E6495F7476D}.Release.ActiveCfg = Release|.NET
+ {842A5DA9-BA2B-4934-8ED6-2E6495F7476D}.Release.Build.0 = Release|.NET
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/tests/NLogTests.vs2005.sln b/tests/NLogTests.vs2005.sln
new file mode 100644
index 0000000..5501f05
--- /dev/null
+++ b/tests/NLogTests.vs2005.sln
@@ -0,0 +1,37 @@
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.AsyncBenchmark.vs2005", "NLog.AsyncBenchmark\NLog.AsyncBenchmark.vs2005.csproj", "{F666E83B-3806-4F90-A577-809AA8EEED0E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.vs2005", "..\src\NLog\NLog.vs2005.csproj", "{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.UnitTests.vs2005", "NLog.UnitTests\NLog.UnitTests.vs2005.csproj", "{1653EE05-2720-4A85-BF14-74C4493787B1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLog.Benchmark.vs2005", "NLog.Benchmark\NLog.Benchmark.vs2005.csproj", "{842A5DA9-BA2B-4934-8ED6-2E6495F7476D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F666E83B-3806-4F90-A577-809AA8EEED0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F666E83B-3806-4F90-A577-809AA8EEED0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F666E83B-3806-4F90-A577-809AA8EEED0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F666E83B-3806-4F90-A577-809AA8EEED0E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {020354EE-5073-4BB5-9AA2-A7EADA8CAD09}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1653EE05-2720-4A85-BF14-74C4493787B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1653EE05-2720-4A85-BF14-74C4493787B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1653EE05-2720-4A85-BF14-74C4493787B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1653EE05-2720-4A85-BF14-74C4493787B1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {842A5DA9-BA2B-4934-8ED6-2E6495F7476D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {842A5DA9-BA2B-4934-8ED6-2E6495F7476D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {842A5DA9-BA2B-4934-8ED6-2E6495F7476D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {842A5DA9-BA2B-4934-8ED6-2E6495F7476D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/tools/MakeNLogXSD/AssemblyInfo.cs b/tools/MakeNLogXSD/AssemblyInfo.cs
new file mode 100644
index 0000000..b1c6cc5
--- /dev/null
+++ b/tools/MakeNLogXSD/AssemblyInfo.cs
@@ -0,0 +1,30 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MakeNLogXSD")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MakeNLogXSD")]
+[assembly: AssemblyCopyright("Copyright © 2006 Jaroslaw Kowalski")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/tools/MakeNLogXSD/MakeNLogXSD.vs2005.csproj b/tools/MakeNLogXSD/MakeNLogXSD.vs2005.csproj
new file mode 100644
index 0000000..a877986
--- /dev/null
+++ b/tools/MakeNLogXSD/MakeNLogXSD.vs2005.csproj
@@ -0,0 +1,61 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{BB32EC17-234D-477D-AC37-96EB19A52018}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>MakeNLogXSD</RootNamespace>
+ <AssemblyName>MakeNLogXSD</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AssemblyInfo.cs" />
+ <Compile Include="Program.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\NLog\NLog.vs2005.csproj">
+ <Project>{020354EE-5073-4BB5-9AA2-A7EADA8CAD09}</Project>
+ <Name>NLog.vs2005</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="TemplateNLog.xsd">
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="Properties\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
diff --git a/tools/MakeNLogXSD/Program.cs b/tools/MakeNLogXSD/Program.cs
new file mode 100644
index 0000000..f3b637c
--- /dev/null
+++ b/tools/MakeNLogXSD/Program.cs
@@ -0,0 +1,425 @@
+using System;
+using System.Text;
+
+using NLog;
+using NLog.Config;
+using NLog.Targets.Wrappers;
+using NLog.Targets.Compound;
+
+using System.Xml;
+using System.Reflection;
+using System.IO;
+using System.Collections;
+using System.Xml.Schema;
+using NLog.Conditions;
+using System.ComponentModel;
+using System.Globalization;
+
+namespace MakeNLogXSD
+{
+ class Program
+ {
+ static Hashtable _typeDumped = new Hashtable();
+ static XmlDocument _docXml = new XmlDocument();
+
+ static string XmlDefaultValue(object v)
+ {
+ if (v is bool)
+ {
+ return XmlConvert.ToString((bool)v);
+ }
+ else
+ {
+ return Convert.ToString(v, CultureInfo.InvariantCulture);
+ }
+ }
+
+ static string FindAnnotation(PropertyInfo pi)
+ {
+ string xpath = "//class[@id='T:" + pi.DeclaringType.FullName + "']/property[@name='" + pi.Name + "']/documentation/summary";
+ XmlNode n = _docXml.SelectSingleNode(xpath);
+ if (n != null)
+ {
+ string suffix = "";
+
+ DefaultValueAttribute dva = (DefaultValueAttribute)Attribute.GetCustomAttribute(pi, typeof(DefaultValueAttribute));
+ if (dva != null)
+ suffix += " Default value is: " + XmlDefaultValue(dva.Value);
+
+ return n.InnerText + suffix;
+ }
+ else
+ return null;
+ }
+
+ static string SimpleTypeName(Type t)
+ {
+ if (t == typeof(byte))
+ return "xs:byte";
+ if (t == typeof(int))
+ return "xs:integer";
+ if (t == typeof(long))
+ return "xs:long";
+ if (t == typeof(string))
+ return "xs:string";
+ if (t == typeof(bool))
+ return "xs:boolean";
+
+ TargetAttribute ta = (TargetAttribute)Attribute.GetCustomAttribute(t, typeof(TargetAttribute));
+ if (ta != null)
+ return ta.Name;
+
+ LayoutAttribute la = (LayoutAttribute)Attribute.GetCustomAttribute(t, typeof(LayoutAttribute));
+ if (la != null)
+ return la.Name;
+
+ return t.Name;
+ }
+
+ static string MakeCamelCase(string s)
+ {
+ if (s.Length < 1)
+ return s.ToLower();
+
+ int firstLower = s.Length;
+ for (int i = 0; i < s.Length; ++i)
+ {
+ if (Char.IsLower(s[i]))
+ {
+ firstLower = i;
+ break;
+ }
+ }
+
+ if (firstLower == 0)
+ return s;
+
+ // DBType
+ if (firstLower != 1 && firstLower != s.Length)
+ firstLower--;
+ return s.Substring(0, firstLower).ToLower() + s.Substring(firstLower);
+ }
+
+ static void DumpEnum(XmlTextWriter xtw, Type t)
+ {
+ xtw.WriteStartElement("xs:simpleType");
+ xtw.WriteAttributeString("name", SimpleTypeName(t));
+
+ xtw.WriteStartElement("xs:restriction");
+ xtw.WriteAttributeString("base", "xs:string");
+
+ foreach (FieldInfo fi in t.GetFields())
+ {
+ if (fi.Name.IndexOf("__") >= 0)
+ continue;
+ xtw.WriteStartElement("xs:enumeration");
+ xtw.WriteAttributeString("value", fi.Name);
+ xtw.WriteEndElement();
+ }
+
+ xtw.WriteEndElement(); // xs:restriction
+ xtw.WriteEndElement(); // xs:simpleType
+ }
+
+ static void DumpType(XmlTextWriter xtw, Type t)
+ {
+ if (_typeDumped[t] != null)
+ return;
+
+ _typeDumped[t] = t;
+
+ if (t.IsArray)
+ return;
+
+ if (t.IsPrimitive)
+ return;
+
+ if (t == typeof(string))
+ return;
+
+ if (t.IsEnum)
+ {
+ DumpEnum(xtw, t);
+ return;
+ }
+
+ ArrayList typesToDump = new ArrayList();
+
+ typesToDump.Add(t.BaseType);
+
+ xtw.WriteStartElement("xs:complexType");
+ xtw.WriteAttributeString("name", SimpleTypeName(t));
+ if (t.IsAbstract)
+ xtw.WriteAttributeString("abstract", "true");
+
+ if (t.BaseType != typeof(object) || t.GetInterface("NLog.ILayout") != null)
+ {
+ xtw.WriteStartElement("xs:complexContent");
+ xtw.WriteStartElement("xs:extension");
+ if (t.BaseType != typeof(object))
+ {
+ xtw.WriteAttributeString("base", SimpleTypeName(t.BaseType));
+ }
+ else
+ {
+ xtw.WriteAttributeString("base", "ILayout");
+ }
+ }
+
+ xtw.WriteStartElement("xs:choice");
+ xtw.WriteAttributeString("minOccurs", "0");
+ xtw.WriteAttributeString("maxOccurs", "unbounded");
+
+ foreach (PropertyInfo pi in t.GetProperties())
+ {
+ if (pi.DeclaringType != t)
+ continue;
+
+ ArrayParameterAttribute apa = (ArrayParameterAttribute)Attribute.GetCustomAttribute(pi, typeof(ArrayParameterAttribute));
+ if (apa != null)
+ {
+ xtw.WriteStartElement("xs:element");
+ xtw.WriteAttributeString("name", apa.ElementName);
+ xtw.WriteAttributeString("type", SimpleTypeName(apa.ItemType));
+ xtw.WriteAttributeString("minOccurs", "0");
+ xtw.WriteAttributeString("maxOccurs", "unbounded");
+ xtw.WriteEndElement();
+ typesToDump.Add(apa.ItemType);
+ }
+ else if (pi.PropertyType.IsValueType || pi.PropertyType.IsEnum || pi.PropertyType == typeof(string) || typeof(ILayout).IsAssignableFrom(pi.PropertyType))
+ {
+ if (pi.CanWrite && pi.CanRead && ((pi.GetSetMethod().Attributes & MethodAttributes.ReuseSlot) == 0) && (pi.Name != "Layout" || !typeof(TargetWithLayout).IsAssignableFrom(pi.DeclaringType)))
+ {
+ xtw.WriteStartElement("xs:element");
+ xtw.WriteAttributeString("name", MakeCamelCase(pi.Name));
+ xtw.WriteAttributeString("type", SimpleTypeName(pi.PropertyType));
+ xtw.WriteAttributeString("minOccurs", "0");
+ xtw.WriteAttributeString("maxOccurs", "1");
+ xtw.WriteEndElement();
+ }
+ }
+ }
+
+ if (t == typeof(WrapperTargetBase))
+ {
+ xtw.WriteStartElement("xs:element");
+ xtw.WriteAttributeString("name", "target");
+ xtw.WriteAttributeString("type", "Target");
+ xtw.WriteAttributeString("minOccurs", "1");
+ xtw.WriteAttributeString("maxOccurs", "1");
+ xtw.WriteEndElement();
+
+ xtw.WriteStartElement("xs:element");
+ xtw.WriteAttributeString("name", "wrapper-target");
+ xtw.WriteAttributeString("type", "WrapperTargetBase");
+ xtw.WriteAttributeString("minOccurs", "1");
+ xtw.WriteAttributeString("maxOccurs", "1");
+ xtw.WriteEndElement();
+
+ xtw.WriteStartElement("xs:element");
+ xtw.WriteAttributeString("name", "compound-target");
+ xtw.WriteAttributeString("type", "CompoundTargetBase");
+ xtw.WriteAttributeString("minOccurs", "1");
+ xtw.WriteAttributeString("maxOccurs", "1");
+ xtw.WriteEndElement();
+ }
+
+ if (t == typeof(CompoundTargetBase))
+ {
+ xtw.WriteStartElement("xs:element");
+ xtw.WriteAttributeString("name", "target");
+ xtw.WriteAttributeString("type", "Target");
+ xtw.WriteAttributeString("minOccurs", "1");
+ xtw.WriteAttributeString("maxOccurs", "unbounded");
+ xtw.WriteEndElement();
+
+ xtw.WriteStartElement("xs:element");
+ xtw.WriteAttributeString("name", "wrapper-target");
+ xtw.WriteAttributeString("type", "WrapperTargetBase");
+ xtw.WriteAttributeString("minOccurs", "1");
+ xtw.WriteAttributeString("maxOccurs", "1");
+ xtw.WriteEndElement();
+
+ xtw.WriteStartElement("xs:element");
+ xtw.WriteAttributeString("name", "compound-target");
+ xtw.WriteAttributeString("type", "CompoundTargetBase");
+ xtw.WriteAttributeString("minOccurs", "1");
+ xtw.WriteAttributeString("maxOccurs", "1");
+ xtw.WriteEndElement();
+ }
+
+ xtw.WriteEndElement();
+
+ foreach (PropertyInfo pi in t.GetProperties())
+ {
+ if (pi.DeclaringType != t)
+ continue;
+
+ if (pi.IsDefined(typeof(ArrayParameterAttribute), false))
+ continue;
+
+ if (!pi.PropertyType.IsValueType && !pi.PropertyType.IsEnum && pi.PropertyType != typeof(string))
+ continue;
+
+ if (!pi.CanWrite)
+ continue;
+
+ xtw.WriteStartElement("xs:attribute");
+ xtw.WriteAttributeString("name", MakeCamelCase(pi.Name));
+ if (pi.IsDefined(typeof(AcceptsLayoutAttribute), false))
+ xtw.WriteAttributeString("type", "NLogLayout");
+ else if (pi.IsDefined(typeof(AcceptsConditionAttribute), false))
+ xtw.WriteAttributeString("type", "NLogCondition");
+ else
+ xtw.WriteAttributeString("type", SimpleTypeName(pi.PropertyType));
+ DefaultValueAttribute dva = (DefaultValueAttribute)Attribute.GetCustomAttribute(pi, typeof(DefaultValueAttribute));
+ if (dva != null)
+ xtw.WriteAttributeString("default", XmlDefaultValue(dva.Value));
+
+ string annotation = FindAnnotation(pi);
+ if (annotation != null)
+ {
+ xtw.WriteStartElement("xs:annotation");
+ xtw.WriteStartElement("xs:documentation");
+ xtw.WriteString(annotation);
+ xtw.WriteEndElement();
+ xtw.WriteEndElement();
+ }
+
+ typesToDump.Add(pi.PropertyType);
+ xtw.WriteEndElement();
+ }
+
+ /*
+ if (typeof(Target).IsAssignableFrom(t))
+ {
+ TargetAttribute ta = (TargetAttribute)Attribute.GetCustomAttribute(t, typeof(TargetAttribute));
+ if (ta != null && !ta.IgnoresLayout)
+ {
+ xtw.WriteStartElement("xs:attribute");
+ xtw.WriteAttributeString("name", "layout");
+ xtw.WriteAttributeString("type", "NLogLayout");
+ xtw.WriteEndElement();
+ }
+ }
+ */
+
+ if (t.BaseType != typeof(object) || t.GetInterface("NLog.ILayout") != null)
+ {
+ xtw.WriteEndElement(); // xs:extension
+ xtw.WriteEndElement(); // xs:complexContent
+ }
+
+ xtw.WriteEndElement(); // xs:complexType
+
+ foreach (Type ttd in typesToDump)
+ {
+ DumpType(xtw, ttd);
+ }
+ }
+
+ static int Main(string[] args)
+ {
+ if (args.Length < 2)
+ {
+ Console.WriteLine("Usage: MakeNLogXSD outputfile.xsd path_to_doc.xml");
+ return 1;
+ }
+
+ try
+ {
+ _docXml.Load(args[1]);
+
+ for (int i = 2; i < args.Length; ++i)
+ {
+ try
+ {
+ Assembly asm = Assembly.Load(args[i]);
+ TargetFactory.AddTargetsFromAssembly(asm, "");
+ LayoutRendererFactory.AddLayoutRenderersFromAssembly(asm, "");
+ FilterFactory.AddFiltersFromAssembly(asm, "");
+ LayoutFactory.AddLayoutsFromAssembly(asm, "");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("WARNING: {0}", ex.Message);
+ }
+ }
+
+ StringWriter sw = new StringWriter();
+
+ sw.Write("<root xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">");
+
+ XmlTextWriter xtw = new XmlTextWriter(sw);
+ xtw.Namespaces = false;
+ xtw.Formatting = Formatting.Indented;
+
+ _typeDumped[typeof(object)] = 1;
+ _typeDumped[typeof(Target)] = 1;
+ _typeDumped[typeof(TargetWithLayout)] = 1;
+ _typeDumped[typeof(TargetWithLayoutHeaderAndFooter)] = 1;
+ _typeDumped[typeof(ILayout)] = 1;
+ _typeDumped[typeof(ILayoutWithHeaderAndFooter)] = 1;
+
+ foreach (Type targetType in NLog.TargetFactory.TargetTypes)
+ {
+ DumpType(xtw, targetType);
+ }
+ foreach (Type t in FilterFactory.FilterTypes)
+ {
+ DumpType(xtw, t);
+ }
+ foreach (Type t in LayoutFactory.LayoutTypes)
+ {
+ DumpType(xtw, t);
+ }
+ xtw.Flush();
+ sw.Write("</root>");
+ sw.Flush();
+
+ XmlDocument doc2 = new XmlDocument();
+ doc2.LoadXml(sw.ToString());
+
+ using (Stream templateStream = Assembly.GetEntryAssembly().GetManifestResourceStream("MakeNLogXSD.TemplateNLog.xsd"))
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.Load(templateStream);
+
+ XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
+ nsmgr.AddNamespace("", "http://www.w3.org/2001/XMLSchema");
+
+ XmlNode n = doc.SelectSingleNode("//types-go-here");
+
+ foreach (XmlElement el in doc2.DocumentElement.ChildNodes)
+ {
+ XmlNode importedNode = doc.ImportNode(el, true);
+ n.ParentNode.InsertBefore(importedNode, n);
+ }
+ n.ParentNode.RemoveChild(n);
+
+ n = doc.SelectSingleNode("//filters-go-here");
+ foreach (Type t in FilterFactory.FilterTypes)
+ {
+ FilterAttribute fa = (FilterAttribute)Attribute.GetCustomAttribute(t, typeof(FilterAttribute));
+ XmlElement el = doc.CreateElement("xs:element", XmlSchema.Namespace);
+ el.SetAttribute("name", fa.Name);
+ el.SetAttribute("type", SimpleTypeName(t));
+ n.ParentNode.InsertBefore(el, n);
+ }
+ n.ParentNode.RemoveChild(n);
+
+ Console.WriteLine("Saving schema to: {0}", args[0]);
+ doc.Save(args[0]);
+ return 0;
+ }
+
+
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("ERROR: {0}", ex);
+ return 1;
+ }
+ }
+ }
+}
diff --git a/tools/MakeNLogXSD/TemplateNLog.xsd b/tools/MakeNLogXSD/TemplateNLog.xsd
new file mode 100644
index 0000000..a6bd474
--- /dev/null
+++ b/tools/MakeNLogXSD/TemplateNLog.xsd
@@ -0,0 +1,268 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<xs:schema id="NLog"
+ targetNamespace="http://www.nlog-project.org/schemas/NLog.xsd"
+ elementFormDefault="qualified"
+ xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:mstns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:element name="nlog" type="NLogConfiguration" />
+ <xs:element name="target" type="Target" abstract="true" />
+
+ <xs:complexType name="NLogConfiguration">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="extensions" type="NLogExtensions" />
+ <xs:element name="include" type="NLogInclude" />
+ <xs:element name="variable" type="NLogVariable" />
+ <xs:element name="targets" type="NLogTargets" />
+ <xs:element name="rules" type="NLogRules" />
+ </xs:choice>
+ <xs:attribute name="autoReload" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation>Watch config file for changes and reload automatically.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="internalLogToConsole" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation>Print internal NLog messages to the console. Default value is: false</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="internalLogToConsoleError" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation>Print internal NLog messages to the console error output. Default value is: false</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="internalLogFile" type="xs:string">
+ <xs:annotation>
+ <xs:documentation>Write internal NLog messages to the specified file.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="internalLogLevel" type="NLogLevel">
+ <xs:annotation>
+ <xs:documentation>Log level threshold for internal log messages. Default value is: Info.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="globalThreshold" type="NLogLevel">
+ <xs:annotation>
+ <xs:documentation>Global log level threshold for application log messages. Messages below this level won't be logged..</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="throwExceptions" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation>Pass NLog internal exceptions to the application. Default value is: false.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+ <xs:complexType name="NLogTargets">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="default-wrapper" type="WrapperTargetBase" />
+ <xs:element name="default-target-parameters" type="Target" />
+ <xs:element name="target" type="Target" />
+ <xs:element name="wrapper-target" type="WrapperTargetBase" />
+ <xs:element name="compound-target" type="CompoundTargetBase" />
+ </xs:choice>
+ <xs:attribute name="async" type="xs:boolean">
+ <xs:annotation>
+ <xs:documentation>Make all targets within this section asynchronous (creates additional threads but the calling thread isn't blocked by any target writes).</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+ <xs:complexType name="NLogRules">
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="logger" type="NLogLoggerRule" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NLogExtensions">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="add" type="NLogExtensionsAdd" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="NLogExtensionsAdd">
+ <xs:attribute name="prefix" type="xs:string">
+ <xs:annotation>
+ <xs:documentation>Prefix for targets/layout renderers/filters/conditions loaded from this assembly.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="assemblyFile" type="xs:string">
+ <xs:annotation>
+ <xs:documentation>Load NLog extensions from the specified file (*.dll)</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="assembly" type="xs:string">
+ <xs:annotation>
+ <xs:documentation>Load NLog extensions from the specified assembly. Assembly name should be fully qualified.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+ <xs:complexType name="NLogLoggerRule">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="filters" type="NLogFilters" />
+ </xs:choice>
+ <xs:attribute name="name" use="optional">
+ <xs:annotation>
+ <xs:documentation>Name of the logger. May include '*' character which acts like a wildcard. Allowed forms are: *, Name, *Name, Name* and *Name*</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="levels" type="NLogLevelList">
+ <xs:annotation>
+ <xs:documentation>Comma separated list of levels that this rule matches.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="minlevel" type="NLogLevel">
+ <xs:annotation>
+ <xs:documentation>Minimum level that this rule matches.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="maxlevel" type="NLogLevel">
+ <xs:annotation>
+ <xs:documentation>Maximum level that this rule matches.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="level" type="NLogLevel">
+ <xs:annotation>
+ <xs:documentation>Level that this rule matches.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="writeTo" type="NLogTargetIDList">
+ <xs:annotation>
+ <xs:documentation>Comma separated list of target names.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="final" type="xs:boolean" default="false">
+ <xs:annotation>
+ <xs:documentation>Ignore further rules if this one matches.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+ <xs:complexType name="NLogFilters">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <filters-go-here xmlns=""/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:simpleType name="NLogLevel">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Trace" />
+ <xs:enumeration value="Debug" />
+ <xs:enumeration value="Info" />
+ <xs:enumeration value="Warn" />
+ <xs:enumeration value="Error" />
+ <xs:enumeration value="Fatal" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="NLogLevelList">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="(|Trace|Debug|Info|Warn|Error|Fatal)(,(Trace|Debug|Info|Warn|Error|Fatal))*" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="NLogInclude">
+ <xs:attribute name="file" type="NLogLayout" use="required">
+ <xs:annotation>
+ <xs:documentation>Name of the file to be included. The name is relative to the name of the current config file.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="ignoreErrors" type="xs:boolean" use="optional" default="false">
+ <xs:annotation>
+ <xs:documentation>Ignore any errors in the include file.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+ <xs:complexType name="NLogVariable">
+ <xs:attribute name="name" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation>Variable name.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="value" type="NLogLayout" use="required">
+ <xs:annotation>
+ <xs:documentation>Variable value.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+ <xs:simpleType name="NLogTargetIDList">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="(|([a-zA-Z][a-zA-Z0-9_\-]*))(,([a-zA-Z][a-zA-Z0-9_\-]*))*" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="Target" abstract="true">
+ <xs:attribute name="name" use="optional" />
+ </xs:complexType>
+
+ <xs:complexType name="ILayout" abstract="true">
+ </xs:complexType>
+
+ <xs:complexType name="ILayoutWithHeaderAndFooter" abstract="true">
+ <xs:complexContent>
+ <xs:extension base="ILayout" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="TargetWithLayout" abstract="true">
+ <xs:complexContent>
+ <xs:extension base="Target">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="layout" type="ILayout" minOccurs="0" maxOccurs="1"/>
+ </xs:choice>
+ <xs:attribute name="layout" type="NLogLayout" use="optional" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="TargetWithLayoutHeaderAndFooter" abstract="true">
+ <xs:complexContent>
+ <xs:extension base="TargetWithLayout">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="header" type="ILayout" minOccurs="0" maxOccurs="1" />
+ <xs:element name="footer" type="ILayout" minOccurs="0" maxOccurs="1" />
+ </xs:choice>
+ <xs:attribute name="layout" type="NLogLayout" default="${longdate}|${level:uppercase=true}|${logger}|${message}">
+ <xs:annotation>
+ <xs:documentation> The text to be rendered. Default value is: ${longdate}|${level:uppercase=true}|${logger}|${message}</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="header" type="NLogLayout">
+ <xs:annotation>
+ <xs:documentation> Header </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="footer" type="NLogLayout">
+ <xs:annotation>
+ <xs:documentation> Footer </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:simpleType name="NLogLayout">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="((\$\{[a-zA-Z][a-zA-Z0-9\-]*(\:[a-zA-Z][a-zA-Z0-9\-]*\=([^\\\:]|\\.)*)*\})|([^\$])|(\$[^\{]))*" />
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="NLogCondition">
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <types-go-here xmlns=""/>
+</xs:schema>
diff --git a/tools/MergeBenchmark.cs b/tools/MergeBenchmark.cs
new file mode 100644
index 0000000..8e92eed
--- /dev/null
+++ b/tools/MergeBenchmark.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Globalization;
+
+class Program
+{
+ static string[] files = {
+ "Benchmark.xml",
+ "Benchmark-log4net-withformat.xml"
+ // "Benchmark-log4net.xml",
+ // "Benchmark-log4net-concrete-logger.xml",
+ };
+
+ static List<List<double>> timings = new List<List<double>>();
+
+ static void Main(string[] args)
+ {
+ XmlDocument doc = new XmlDocument();
+ for (int i = 0; i < files.Length; ++i)
+ {
+ doc.Load(files[i]);
+ List<double> tt = new List<double>();
+
+ foreach (XmlElement timing in doc.SelectNodes("//timing"))
+ {
+ double val = Convert.ToDouble(timing.GetAttribute("nanosecondsPerLog"), CultureInfo.InvariantCulture);
+ tt.Add(val);
+ }
+ timings.Add(tt);
+ }
+ int ordinal = 0;
+
+ foreach (XmlElement el in doc.SelectNodes("//timing"))
+ {
+ string section = ((XmlElement)el.ParentNode).GetAttribute("logger");
+
+ if (ordinal % 4 == 0)
+ {
+ Console.WriteLine();
+ Console.WriteLine("\"{0}\"\t\"NLog\"\t\"Log4Net\"", section);
+ }
+ Console.Write("\"{0}\"", el.GetAttribute("name"));
+ for (int i = 0; i < files.Length; ++i)
+ {
+ Console.Write("\t{0}",Math.Round(timings[i][ordinal],3));
+ }
+ Console.WriteLine();
+ ordinal++;
+ }
+ }
+}
diff --git a/tools/NDocSyntax_LICENSE.txt b/tools/NDocSyntax_LICENSE.txt
new file mode 100644
index 0000000..3da7706
--- /dev/null
+++ b/tools/NDocSyntax_LICENSE.txt
@@ -0,0 +1,28 @@
+
+Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/tools/PrettyPrinter.pdb b/tools/PrettyPrinter.pdb
new file mode 100644
index 0000000..76b8557
Binary files /dev/null and b/tools/PrettyPrinter.pdb differ
diff --git a/tools/PrettyPrinter/App.ico b/tools/PrettyPrinter/App.ico
new file mode 100644
index 0000000..3a5525f
Binary files /dev/null and b/tools/PrettyPrinter/App.ico differ
diff --git a/tools/PrettyPrinter/AssemblyInfo.cs b/tools/PrettyPrinter/AssemblyInfo.cs
new file mode 100644
index 0000000..14c75ca
--- /dev/null
+++ b/tools/PrettyPrinter/AssemblyInfo.cs
@@ -0,0 +1,58 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.0.0")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+// (*) If no key is specified, the assembly is not signed.
+// (*) KeyName refers to a key that has been installed in the Crypto Service
+// Provider (CSP) on your machine. KeyFile refers to a file which contains
+// a key.
+// (*) If the KeyFile and the KeyName values are both specified, the
+// following processing occurs:
+// (1) If the KeyName can be found in the CSP, that key is used.
+// (2) If the KeyName does not exist and the KeyFile does exist, the key
+// in the KeyFile is installed into the CSP and used.
+// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+// When specifying the KeyFile, the location of the KeyFile should be
+// relative to the project output directory which is
+// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
+// located in the project directory, you would specify the AssemblyKeyFile
+// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+// documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]
diff --git a/tools/PrettyPrinter/Class1.cs b/tools/PrettyPrinter/Class1.cs
new file mode 100644
index 0000000..dad9a02
--- /dev/null
+++ b/tools/PrettyPrinter/Class1.cs
@@ -0,0 +1,417 @@
+using System;
+using System.IO;
+using System.Text.RegularExpressions;
+using System.Xml;
+
+namespace CSharpPrettyPrint
+{
+ /// <summary>
+ /// Summary description for Class1.
+ /// </summary>
+ class Class1
+ {
+ static string[] csharpKeywords = {
+ "class",
+ "abstract",
+ "event",
+ "new",
+ "struct",
+ "as",
+ "explicit",
+ "null",
+ "switch",
+ "base",
+ "extern",
+ "object",
+ "this",
+ "bool",
+ "false",
+ "operator",
+ "throw",
+ "break",
+ "finally",
+ "out",
+ "true",
+ "byte",
+ "fixed",
+ "override",
+ "try",
+ "case",
+ "float",
+ "params",
+ "typeof",
+ "catch",
+ "for",
+ "private",
+ "uint",
+ "char",
+ "foreach",
+ "protected",
+ "ulong",
+ "checked",
+ "goto",
+ "public",
+ "unchecked",
+ "if",
+ "readonly",
+ "unsafe",
+ "const",
+ "implicit",
+ "ref",
+ "ushort",
+ "continue",
+ "in",
+ "return",
+ "using",
+ "decimal",
+ "int",
+ "sbyte",
+ "virtual",
+ "default",
+ "interface",
+ "sealed",
+ "volatile",
+ "delegate",
+ "internal",
+ "short",
+ "void",
+ "do",
+ "is",
+ "sizeof",
+ "while",
+ "double",
+ "lock",
+ "stackalloc",
+ "else",
+ "long",
+ "static",
+ "enum",
+ "namespace",
+ "string",
+ };
+
+ static string[] jscriptKeywords = {
+ "class", "break", "delete", "function", "return", "typeof",
+ "case", "do", "if", "switch", "var",
+ "catch", "else", "in", "this", "void",
+ "continue", "false", "instanceof", "throw", "while",
+ "debugger", "finally", "new", "true", "with",
+ "default", "for", "null", "try",
+
+ "abstract", "double", "goto", "native", "static",
+ "boolean", "enum", "implements", "package", "super",
+ "byte", "export", "import", "private", "synchronized",
+ "char", "extends", "int", "protected", "throws",
+ "final", "interface", "public", "transient",
+ "const", "float", "long", "short", "volatile",
+ };
+
+ static string MarkKeyword(string language, string l, string k)
+ {
+ Regex regex = new Regex("\\b"+k+"\\b");
+ return regex.Replace(l, "<span class='k'>" + k + "</span>");
+ }
+
+ static string PrettyPrintSegment(string language, string line, int p0, int p1, char mode)
+ {
+ string l0 = line.Substring(p0, p1 - p0);
+ l0 = l0.Replace("&", "&");
+ l0 = l0.Replace("<", "<");
+ l0 = l0.Replace(">", ">");
+ // l0 = l0.Replace(" ", " ");
+ l0 = l0.Replace("'", "'");
+ l0 = l0.Replace("\"", """);
+
+ switch (mode)
+ {
+ case 'S':
+ return "<span class='s'>" + l0 + "</span>";
+
+ case 'C': /* comment
+ *
+ * */
+ return "<span class='c'>" + l0 + "</span>";
+ case 'R':
+ return "<span class='r'>" + l0 + "</span>";
+ }
+
+ int p = l0.IndexOf("//");
+ string l1 = "";
+ if (p >= 0)
+ {
+ l1 = l0.Substring(p);
+ l0 = l0.Substring(0, p);
+
+ l1 = "<span class='c'>" + l1 + "</span>";
+ }
+
+ switch (language)
+ {
+ case "csharp":
+ foreach (string kwd in csharpKeywords)
+ {
+ l0 = MarkKeyword(language, l0, kwd);
+ }
+ break;
+
+ case "jscript":
+ foreach (string kwd in jscriptKeywords)
+ {
+ l0 = MarkKeyword(language, l0, kwd);
+ }
+ break;
+ }
+
+ l0 += l1;
+
+ return l0;
+ }
+
+ static void WriteAttributes(TextWriter output, XmlTextReader xtr)
+ {
+ for (int i = 0; i < xtr.AttributeCount; i++)
+ {
+ xtr.MoveToAttribute(i);
+ if (xtr.Prefix == "xml")
+ continue;
+ output.Write(" <span class='a'>{0}</span>=<span class='at'>\"{1}\"</span>", xtr.Name, xtr.Value);
+ }
+ xtr.MoveToElement();
+ }
+
+ static void PrettyPrintXml(TextWriter output, TextReader input)
+ {
+ XmlTextReader xtr = new XmlTextReader(input);
+ xtr.WhitespaceHandling = WhitespaceHandling.All;
+ while (xtr.Read())
+ {
+ switch (xtr.NodeType)
+ {
+ case XmlNodeType.Element:
+ output.Write("<span class='b'><</span>");
+ output.Write("<span class='e'>");
+ output.Write(xtr.Name);
+ output.Write("</span>");
+ WriteAttributes(output, xtr);
+ output.Write("<span class='b'>");
+ if (xtr.IsEmptyElement)
+ output.Write("/");
+ output.Write("></span>");
+ break;
+
+ case XmlNodeType.EndElement:
+ output.Write("<span class='b'></</span>");
+ output.Write("<span class='e'>");
+ output.Write(xtr.Name);
+ output.Write("</span>");
+ output.Write("<span class='b'>");
+ output.Write("></span>");
+ break;
+
+ case XmlNodeType.Comment:
+ output.Write("<span class='c'><!--");
+ output.Write(xtr.Value);
+ output.Write("--></span>");
+ break;
+
+ case XmlNodeType.XmlDeclaration:
+ output.Write("<span class='b'><?</span>");
+ output.Write("<span class='x'>xml {0}</span>", xtr.Value);
+ output.Write(" <span class='b'>?></span>");
+ break;
+
+ case XmlNodeType.SignificantWhitespace:
+ case XmlNodeType.Whitespace:
+ case XmlNodeType.Text:
+ output.Write(xtr.Value);
+ break;
+
+ default:
+ throw new Exception("Unsupported XML node type: " + xtr.NodeType);
+ }
+ }
+ }
+
+ static void PrettyPrint(string language, TextWriter output, TextReader input)
+ {
+ string line;
+ char mode = 'P';
+
+ while ((line = input.ReadLine()) != null)
+ {
+ int p;
+ int p0 = 0;
+
+ string line2 = "";
+
+ for (int i = 0; i < line.Length; ++i)
+ {
+ char c = line[i];
+ char c2 = (char)0;
+ if (i + 1 < line.Length)
+ c2 = line[i + 1];
+
+ switch (mode)
+ {
+ case 'C': // comment
+ if (c == '*' && c2 == '/')
+ {
+ i += 2;
+ line2 += PrettyPrintSegment(language, line, p0, i, mode);
+ p0 = i;
+ mode = 'P';
+ }
+ break;
+
+ case 'S': // string
+ if (c == '\\')
+ {
+ i++;
+ break;
+ }
+ if (c == '"')
+ {
+ i++;
+ line2 += PrettyPrintSegment(language, line, p0, i, mode);
+ p0 = i;
+ mode = 'P';
+ }
+ break;
+
+ case 'R': // char
+ if (c == '\\')
+ {
+ i++;
+ break;
+ }
+ if (c == '\'')
+ {
+ i++;
+ line2 += PrettyPrintSegment(language, line, p0, i, mode);
+ p0 = i;
+ mode = 'P';
+ }
+ break;
+
+ case 'P': // plain
+ if (c == '"')
+ {
+ line2 += PrettyPrintSegment(language, line, p0, i, mode);
+ p0 = i;
+ mode = 'S';
+ }
+ else if (c == '\'')
+ {
+ line2 += PrettyPrintSegment(language, line, p0, i, mode);
+ p0 = i;
+ mode = 'R';
+ }
+ else if (c == '/' && c2 == '*')
+ {
+ line2 += PrettyPrintSegment(language, line, p0, i, mode);
+ p0 = i;
+ mode = 'C';
+ }
+ break;
+ }
+ }
+
+ line2 += PrettyPrintSegment(language, line, p0, line.Length, mode);
+
+ line = line2;
+
+ output.WriteLine(line);
+ }
+ }
+
+ static void Usage(string error)
+ {
+ Console.WriteLine(error);
+ Console.WriteLine("Usage: PrettyPrinter.exe -l csharp|cpp|jscript|vb|xml -i infile -o outfile -m xml|html -s stylesheet.css");
+ }
+
+ [STAThread]
+ static int Main(string[] args)
+ {
+ string language = "csharp";
+ string stylesheet = "style.css";
+ string mode = "html";
+ string inputFile = null;
+ string outputFile = null;
+
+ for (int i = 0; i < args.Length; ++i)
+ {
+ if (args[i] == "-l" && i + 1 < args.Length)
+ {
+ language = args[++i];
+ continue;
+ }
+ if (args[i] == "-i" && i + 1 < args.Length)
+ {
+ inputFile = args[++i];
+ continue;
+ }
+
+ if (args[i] == "-o" && i + 1 < args.Length)
+ {
+ outputFile = args[++i];
+ continue;
+ }
+
+ if (args[i] == "-s" && i + 1 < args.Length)
+ {
+ stylesheet = args[++i];
+ continue;
+ }
+
+ if (args[i] == "-m" && i + 1 < args.Length)
+ {
+ mode = args[++i];
+ continue;
+ }
+
+ Usage("Unknown parameter: " + args[i]);
+ return 1;
+ }
+
+ if (inputFile == null)
+ {
+ Usage("No input file given.");
+ return 1;
+ }
+
+ if (outputFile == null)
+ {
+ Usage("No output file given.");
+ return 1;
+ }
+
+ using (StreamReader infile = new StreamReader(inputFile, System.Text.Encoding.Default))
+ {
+ using (StreamWriter outfile = new StreamWriter(outputFile, false, System.Text.Encoding.UTF8))
+ {
+ if (mode == "html")
+ {
+ outfile.WriteLine("<html>");
+ outfile.WriteLine("<head>");
+ outfile.Write("<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\" />", stylesheet);
+ outfile.WriteLine("</head>");
+ outfile.WriteLine("<body class=\"example\">");
+ }
+ outfile.Write("<pre xml:space='preserve' class='{0}'>", language);
+ if (language == "xml")
+ PrettyPrintXml(outfile, infile);
+ else
+ PrettyPrint(language, outfile, infile);
+ outfile.Write("</pre>");
+ if (mode == "html")
+ {
+ outfile.WriteLine("</body>");
+ outfile.WriteLine("</html>");
+ }
+ }
+ }
+ return 0;
+ }
+ }
+}
diff --git a/tools/PrettyPrinter/PrettyPrinter.csproj b/tools/PrettyPrinter/PrettyPrinter.csproj
new file mode 100644
index 0000000..a4f8280
--- /dev/null
+++ b/tools/PrettyPrinter/PrettyPrinter.csproj
@@ -0,0 +1,104 @@
+<VisualStudioProject>
+ <CSHARP
+ ProjectType = "Local"
+ ProductVersion = "7.10.3077"
+ SchemaVersion = "2.0"
+ ProjectGuid = "{D1CB4BEF-0E76-429E-BE05-735C4DFDE190}"
+ >
+ <Build>
+ <Settings
+ ApplicationIcon = "App.ico"
+ AssemblyKeyContainerName = ""
+ AssemblyName = "PrettyPrinter"
+ AssemblyOriginatorKeyFile = ""
+ DefaultClientScript = "JScript"
+ DefaultHTMLPageLayout = "Grid"
+ DefaultTargetSchema = "IE50"
+ DelaySign = "false"
+ OutputType = "Exe"
+ PreBuildEvent = ""
+ PostBuildEvent = ""
+ RootNamespace = "PrettyPrinter"
+ RunPostBuildEvent = "OnBuildSuccess"
+ StartupObject = ""
+ >
+ <Config
+ Name = "Debug"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "DEBUG;TRACE"
+ DocumentationFile = ""
+ DebugSymbols = "true"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = ""
+ Optimize = "false"
+ OutputPath = "..\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ <Config
+ Name = "Release"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "TRACE"
+ DocumentationFile = ""
+ DebugSymbols = "false"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = ""
+ Optimize = "true"
+ OutputPath = "..\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ </Settings>
+ <References>
+ <Reference
+ Name = "System"
+ AssemblyName = "System"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll"
+ />
+ <Reference
+ Name = "System.Data"
+ AssemblyName = "System.Data"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
+ />
+ <Reference
+ Name = "System.XML"
+ AssemblyName = "System.Xml"
+ HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
+ />
+ </References>
+ </Build>
+ <Files>
+ <Include>
+ <File
+ RelPath = "App.ico"
+ BuildAction = "Content"
+ />
+ <File
+ RelPath = "AssemblyInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Class1.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ </Include>
+ </Files>
+ </CSHARP>
+</VisualStudioProject>
+
diff --git a/tools/PrettyPrinter/PrettyPrinter.sln b/tools/PrettyPrinter/PrettyPrinter.sln
new file mode 100644
index 0000000..3de2a40
--- /dev/null
+++ b/tools/PrettyPrinter/PrettyPrinter.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PrettyPrinter", "PrettyPrinter.csproj", "{D1CB4BEF-0E76-429E-BE05-735C4DFDE190}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {D1CB4BEF-0E76-429E-BE05-735C4DFDE190}.Debug.ActiveCfg = Debug|.NET
+ {D1CB4BEF-0E76-429E-BE05-735C4DFDE190}.Debug.Build.0 = Debug|.NET
+ {D1CB4BEF-0E76-429E-BE05-735C4DFDE190}.Release.ActiveCfg = Release|.NET
+ {D1CB4BEF-0E76-429E-BE05-735C4DFDE190}.Release.Build.0 = Release|.NET
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/tools/ReplaceVersion.cs b/tools/ReplaceVersion.cs
new file mode 100644
index 0000000..210cf3a
--- /dev/null
+++ b/tools/ReplaceVersion.cs
@@ -0,0 +1,122 @@
+//
+// Copyright (c) 2002-2004 Jaroslaw Kowalski <jaak at polbox.com>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of the Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+
+public class ReplaceVersion
+{
+ static string fileNamePattern = "AssemblyInfo.cs";
+ static string newAssemblyVersion;
+
+ public static void Main(string[]args)
+ {
+ if (args.Length < 2)
+ {
+ Console.WriteLine("Usage: ReplaceVersion.exe <root_dir> <new_version_number>");
+ Console.WriteLine();
+ Console.WriteLine("Scans for AssemblyInfo.cs file in <root_dir> and subdirectories");
+ Console.WriteLine("and replaces [assembly: AssemblyVersion()] with given version number");
+ return ;
+ }
+ string dirName = args[0];
+ newAssemblyVersion = args[1];
+
+ DirectoryInfo rootDir = new DirectoryInfo(dirName);
+ ScanDirectory(rootDir);
+ }
+
+ private static void ScanDirectory(DirectoryInfo di)
+ {
+ string fullName = Path.Combine(di.FullName, fileNamePattern);
+
+ if (File.Exists(fullName))
+ {
+ UpdateFile(fullName, di);
+ }
+ foreach (DirectoryInfo subdir in di.GetDirectories())
+ {
+ ScanDirectory(subdir);
+ }
+ }
+
+ private static void UpdateFile(string fullName, DirectoryInfo di)
+ {
+ string tmp = fullName + ".tmp";
+ try
+ {
+ Console.Write("{0}: ", di.FullName);
+ bool changed = false;
+ using(StreamWriter sw = new StreamWriter(tmp))
+ {
+ using(StreamReader sr = new StreamReader(fullName))
+ {
+ string line = null;
+
+ while ((line = sr.ReadLine()) != null)
+ {
+ if (line.StartsWith("[assembly: AssemblyVersion("))
+ {
+ string newValue = String.Format("[assembly: AssemblyVersion(\"{0}\")]", newAssemblyVersion);
+ sw.WriteLine(newValue);
+ if (line != newValue)
+ {
+ changed = true;
+ }
+ }
+ else
+ {
+ sw.WriteLine(line);
+ }
+ }
+ }
+ }
+ if (changed)
+ {
+ Console.WriteLine("Done.");
+ File.Delete(fullName);
+ File.Move(tmp, fullName);
+ }
+ else
+ {
+ Console.WriteLine("No change.");
+ File.Delete(tmp);
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error: {0}", e.Message);
+ File.Delete(tmp);
+ }
+ }
+}
diff --git a/tools/Runner.cs b/tools/Runner.cs
new file mode 100644
index 0000000..a8bae5d
--- /dev/null
+++ b/tools/Runner.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Reflection;
+
+class C1
+{
+ static int Main(string[] args)
+ {
+ try
+ {
+ string assemblyName = args[0];
+ string className = args[1];
+ string methodName = args[2];
+ object[] arguments = new object[args.Length - 3];
+ for (int i = 0; i < arguments.Length; ++i)
+ arguments[i] = args[3 + i];
+
+ Assembly assembly = Assembly.Load(assemblyName);
+ Type type = assembly.GetType(className);
+ if (type == null)
+ throw new Exception(className + " not found in " + assemblyName);
+ MethodInfo method = type.GetMethod(methodName);
+ if (method == null)
+ throw new Exception(methodName + " not found in " + type);
+ object targetObject = null;
+ if (!method.IsStatic)
+ targetObject = Activator.CreateInstance(type);
+ method.Invoke(targetObject, arguments);
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex);
+ return 1;
+ }
+ }
+}
diff --git a/tools/SetupNLog.nsi b/tools/SetupNLog.nsi
new file mode 100644
index 0000000..9e7cd2d
--- /dev/null
+++ b/tools/SetupNLog.nsi
@@ -0,0 +1,255 @@
+SetCompress force
+SetCompressor lzma
+
+!include mui.nsh
+!cd ..
+
+;--------------------------------
+;Interface Settings
+
+ !define MUI_ABORTWARNING
+ !define MUI_COMPONENTSPAGE_SMALLDESC
+
+;--------------------------------
+;Pages
+
+ !insertmacro MUI_PAGE_LICENSE License.txt
+ !insertmacro MUI_PAGE_COMPONENTS
+ !insertmacro MUI_PAGE_DIRECTORY
+ !insertmacro MUI_PAGE_INSTFILES
+
+ !insertmacro MUI_UNPAGE_CONFIRM
+ !insertmacro MUI_UNPAGE_INSTFILES
+
+ !insertmacro MUI_LANGUAGE "English"
+
+; The name of the installer
+Name "NLog ${NLOGVERSION}"
+
+; The file to write
+OutFile "SetupNLog.exe"
+
+; The default installation directory
+InstallDir $PROGRAMFILES\NLog
+
+; The text to prompt the user to enter a directory
+DirText "This will install NLog version ${NLOGVERSION} on your computer. Choose a directory:"
+
+InstType "Full"
+InstType "Typical"
+InstType "Minimal"
+
+; The stuff to install
+Section "NLog Core Files"
+ SectionIn 1 2 3 RO
+ ; Set output path to the installation directory.
+ SetOutPath $INSTDIR
+ File LICENSE.txt
+
+ CreateDirectory "$SMPROGRAMS\NLog"
+ CreateShortCut "$SMPROGRAMS\NLog\Uninstall.lnk" "$INSTDIR\Uninstall.exe" ""
+ CreateShortCut "$SMPROGRAMS\NLog\LICENSE.lnk" "$INSTDIR\License.txt" ""
+ CreateShortCut "$SMPROGRAMS\NLog\NLog Documentation.lnk" "$INSTDIR\help\NLog.chm" ""
+ CreateShortCut "$SMPROGRAMS\NLog\NLog Configuration Examples.lnk" "$INSTDIR\examples" ""
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NLog" "" ""
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NLog" "DisplayName" "NLog - A .NET Logging Library"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NLog" "UninstallString" "$INSTDIR\Uninstall.exe"
+ WriteUninstaller "$INSTDIR\Uninstall.exe"
+SectionEnd ; end the section
+
+SectionGroup ".NET Framework Support"
+
+Section ".NET 1.0 / Visual Studio.NET 2002 (supports all frameworks)"
+ SectionIn 1 2 3
+ SetOutPath $INSTDIR\bin\net-1.0
+ File /r /x _svn "build\net-1.0${OPTIONALDEBUG}\bin\*.*"
+ WriteRegStr HKLM "Software\Microsoft\VisualStudio\7.0\AssemblyFolders\NLog" "" "$INSTDIR\bin\net-1.0"
+SectionEnd
+
+Section ".NET 1.1 / Visual Studio.NET 2003"
+ SectionIn 1 2
+ SetOutPath $INSTDIR\bin\net-1.1
+ File /r /x _svn "build\net-1.1${OPTIONALDEBUG}\bin\*.*"
+ WriteRegStr HKLM "Software\Microsoft\VisualStudio\7.1\AssemblyFolders\NLog" "" "$INSTDIR\bin\net-1.1"
+
+; install schema for intellisense
+ ClearErrors
+ ReadRegStr $0 HKLM Software\Microsoft\VisualStudio\7.1\Setup\VS "VS7CommonDir"
+ IfErrors novsnet
+ DetailPrint "Visual Studio .NET 2003 installed in $0"
+ SetOutPath "$0\Packages\schemas\xml"
+ File "build\net-1.1${OPTIONALDEBUG}\bin\NLog.xsd"
+novsnet:
+
+SectionEnd
+
+Section ".NET 2.0 / Visual Studio 2005"
+ SectionIn 1 2
+ SetOutPath $INSTDIR\bin\net-2.0
+ File /r /x _svn "build\net-2.0${OPTIONALDEBUG}\bin\*.*"
+ WriteRegStr HKLM "Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\NLog" "" "$INSTDIR\bin\net-2.0"
+
+ ClearErrors
+ ReadRegStr $0 HKLM Software\Microsoft\VisualStudio\8.0\Setup\VS "ProductDir"
+ IfErrors novsnet
+ DetailPrint "Visual Studio .NET 2005 installed in $0"
+ SetOutPath "$0\xml\schemas"
+ File "build\net-2.0${OPTIONALDEBUG}\bin\NLog.xsd"
+novsnet:
+
+ ClearErrors
+ ReadRegStr $0 HKCU Software\Microsoft\VisualStudio\8.0 "UserItemTemplatesLocation"
+ IfErrors novsnet2
+ ExpandEnvStrings $1 $0
+ DetailPrint "Installing Visual Studio .NET 2005 item templates in $1"
+ SetOutPath $1
+ File "build\templates\*NLogConfig.zip"
+
+novsnet2:
+ ReadRegStr $0 HKCU Software\Microsoft\VisualStudio\8.0 "VisualStudioLocation"
+ IfErrors novsnet3
+ ExpandEnvStrings $1 $0
+
+ IfFileExists "$1\Code Snippets\Visual C#\My Code Snippets" 0 novsnet3
+ SetOutPath "$1\Code Snippets\Visual C#\My Code Snippets"
+ File "tools\VS2005Snippets\CSharp*.snippet"
+ SetOutPath "$1\Code Snippets\Visual J#\My Code Snippets"
+ File "tools\VS2005Snippets\VJSharp*.snippet"
+ SetOutPath "$1\Code Snippets\Visual Basic\My Code Snippets"
+ File "tools\VS2005Snippets\VB*.snippet"
+
+ ; VC# Express 2005 support
+novsnet3:
+ ReadRegStr $0 HKCU Software\Microsoft\VCSExpress\8.0 "VisualStudioLocation"
+ IfErrors novsnet4
+ ExpandEnvStrings $1 $0
+
+ IfFileExists "$1\Code Snippets\Visual C#\My Code Snippets" 0 novsnet4
+ SetOutPath "$1\Code Snippets\Visual C#\My Code Snippets"
+ File "tools\VS2005Snippets\CSharp*.snippet"
+
+novsnet4:
+ ClearErrors
+ ReadRegStr $0 HKCU Software\Microsoft\VCSExpress\8.0 "UserItemTemplatesLocation"
+ IfErrors novsnet5
+ ExpandEnvStrings $1 $0
+ DetailPrint "Installing Visual C# item templates in $1"
+ SetOutPath $1
+ File "build\templates\CSharp*NLogConfig.zip"
+
+ ; VB.NET Express 2005 support
+novsnet5:
+ ClearErrors
+ ReadRegStr $0 HKCU Software\Microsoft\VBExpress\8.0 "UserItemTemplatesLocation"
+ IfErrors novsnet6
+ ExpandEnvStrings $1 $0
+ DetailPrint "Installing Visual Basic item templates in $1"
+ SetOutPath $1
+ File "build\templates\VisualBasic*NLogConfig.zip"
+
+novsnet6:
+ ReadRegStr $0 HKCU Software\Microsoft\VBExpress\8.0 "VisualStudioLocation"
+ IfErrors novsnet7
+ ExpandEnvStrings $1 $0
+
+ IfFileExists "$1\Code Snippets\Visual Basic\My Code Snippets" 0 novsnet7
+ SetOutPath "$1\Code Snippets\Visual Basic\My Code Snippets"
+ File "tools\VS2005Snippets\VB*.snippet"
+
+ ; VWD Express 2005 support
+novsnet7:
+ ClearErrors
+ ReadRegStr $0 HKCU Software\Microsoft\VWDExpress\8.0 "UserItemTemplatesLocation"
+ IfErrors novsnet8
+ ExpandEnvStrings $1 $0
+ DetailPrint "Installing Visual Web Developer item templates in $1"
+ SetOutPath $1
+ File "build\templates\Web*NLogConfig.zip"
+
+novsnet8:
+
+SectionEnd
+
+SectionGroupEnd
+
+SectionGroup ".NET Compact Framework Support"
+
+Section ".NET Compact Framework 1.0 Support"
+ SectionIn 1
+ SetOutPath $INSTDIR\bin\netcf-1.0
+ File /r /x _svn "build\netcf-1.0${OPTIONALDEBUG}\bin\*.*"
+SectionEnd
+
+Section ".NET Compact Framework 2.0 Support"
+ SectionIn 1
+ SetOutPath $INSTDIR\bin\netcf-2.0
+ File /r /x _svn "build\netcf-2.0${OPTIONALDEBUG}\bin\*.*"
+SectionEnd
+
+SectionGroupEnd
+
+SectionGroup "Mono Support"
+
+Section "Mono 1.0 Profile Support"
+ SectionIn 1
+ SetOutPath $INSTDIR\bin\mono-1.0
+ File /r /x _svn "build\mono-1.0${OPTIONALDEBUG}\bin\*.*"
+SectionEnd
+
+Section "Mono 2.0 Profile Support"
+ SectionIn 1
+ SetOutPath $INSTDIR\bin\mono-2.0
+ File /r /x _svn "build\mono-2.0${OPTIONALDEBUG}\bin\*.*"
+SectionEnd
+
+SectionGroupEnd
+
+Section "Examples"
+ SectionIn 1
+ SetOutPath $INSTDIR\examples
+ File /r /x _svn examples\*.*
+SectionEnd
+
+Section "Documentation"
+ SectionIn 1 2
+ SetOutPath $INSTDIR\help
+ File build\doc\help\NLog.chm
+SectionEnd
+
+Section "Uninstall"
+ DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NLog"
+ DeleteRegKey HKLM "Software\Microsoft\VisualStudio\7.0\AssemblyFolders\NLog"
+ DeleteRegKey HKLM "Software\Microsoft\VisualStudio\7.1\AssemblyFolders\NLog"
+ DeleteRegKey HKLM "Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\NLog"
+
+ ClearErrors
+ ReadRegStr $0 HKLM Software\Microsoft\VisualStudio\7.1\Setup\VS "VS7CommonDir"
+ IfErrors novsnet2
+ Delete "$0\Packages\schemas\xml\NLog.xsd"
+
+novsnet2:
+ ClearErrors
+ ReadRegStr $0 HKLM Software\Microsoft\VisualStudio\8.0\Setup\VS "ProductDir"
+ IfErrors novsnet3
+ Delete "$0\xml\schemas\NLog.xsd"
+
+novsnet3:
+ ClearErrors
+ ReadRegStr $0 HKCU Software\Microsoft\VisualStudio\8.0 "UserItemTemplatesLocation"
+ IfErrors novsnet4
+ ExpandEnvStrings $1 $0
+ Delete "$1\*NLogConfig.zip"
+
+novsnet4:
+
+ Delete "$SMPROGRAMS\NLog\*.lnk"
+ RMDir "$SMPROGRAMS\NLog"
+
+ RMDir /r "$INSTDIR"
+SectionEnd
+; eof
+
+Function .onInstSuccess
+ ExecShell open '$SMPROGRAMS\NLog'
+FunctionEnd
+
diff --git a/tools/SyncVSProjectItems.cs b/tools/SyncVSProjectItems.cs
new file mode 100644
index 0000000..4e43113
--- /dev/null
+++ b/tools/SyncVSProjectItems.cs
@@ -0,0 +1,231 @@
+//
+// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak at jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+using System;
+using System.IO;
+using System.Globalization;
+using System.Collections;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Xml;
+
+using NAnt.Core;
+using NAnt.Core.Attributes;
+using NAnt.Core.Types;
+using NAnt.Core.Util;
+
+namespace Tools
+{
+ [TaskName("sync-vs-project-items")]
+ public class SyncVSProjectItems : Task
+ {
+ private FileSet _sourceFiles;
+ private FileSet _projectFiles;
+ private FileSet _resourceFiles;
+
+ [BuildElement("source-files")]
+ public FileSet SourceFiles {
+ get { return _sourceFiles; }
+ set { _sourceFiles = value; }
+ }
+
+ [BuildElement("project-files")]
+ public FileSet ProjectFiles {
+ get { return _projectFiles; }
+ set { _projectFiles = value; }
+ }
+
+ [BuildElement("resource-files")]
+ public FileSet ResourceFiles {
+ get { return _resourceFiles; }
+ set { _resourceFiles = value; }
+ }
+
+ private Hashtable _relativeSourceFiles = new Hashtable();
+ private Hashtable _relativeResourceFiles = new Hashtable();
+
+ private int _added = 0;
+ private int _removed = 0;
+
+ private static string RelativePath(string baseDir, string rootedName)
+ {
+ if (rootedName.ToLower().StartsWith(baseDir.ToLower()))
+ {
+ string s = rootedName.Substring(baseDir.Length);
+
+ return s;
+ }
+ throw new Exception("Path " + rootedName + " is not within " + baseDir);
+ }
+
+ protected override void ExecuteTask() {
+ string baseDir = SourceFiles.BaseDirectory.FullName;
+ if (!baseDir.EndsWith("\\"))
+ baseDir = baseDir + "\\";
+
+ foreach (string s in SourceFiles.FileNames)
+ {
+ _relativeSourceFiles[RelativePath(baseDir, s)] = s;
+ }
+
+ foreach (string projectFile in ProjectFiles.FileNames)
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.Load(projectFile);
+ _added = 0;
+ _removed = 0;
+
+ if (doc.SelectSingleNode("//Files/Include") != null)
+ {
+ Log(Level.Verbose, "Visual Studio 2002/2003-style project.");
+ ProcessOldProject(doc);
+ }
+ else
+ {
+ Log(Level.Verbose, "MSBuild-style project.");
+ ProcessMSBuildProject(doc);
+ }
+ if (_added + _removed > 0)
+ {
+ Log(Level.Info, "Project: {0} Added: {1} Removed: {2}", projectFile, _added, _removed);
+ doc.Save(projectFile);
+ }
+ }
+ }
+
+ private void ProcessOldProject(XmlDocument doc)
+ {
+ SyncOldProjectItem(doc, "Compile", "Code", _relativeSourceFiles);
+ SyncOldProjectItem(doc, "EmbeddedResource", null, _relativeResourceFiles);
+ }
+
+ private void SyncOldProjectItem(XmlDocument doc, string buildAction, string subType, Hashtable directoryFiles)
+ {
+ Hashtable projectSourceFiles = new Hashtable();
+
+ foreach (XmlElement el in doc.SelectNodes("//File[@BuildAction='" + buildAction + "']"))
+ {
+ string name = el.GetAttribute("RelPath");
+ projectSourceFiles[name] = el;
+ }
+
+ XmlElement filesInclude = (XmlElement)doc.SelectSingleNode("//Files/Include");
+
+ foreach (string s in projectSourceFiles.Keys)
+ {
+ if (!directoryFiles.Contains(s))
+ {
+ XmlElement el = (XmlElement)projectSourceFiles[s];
+ Log(Level.Verbose, "File {0} not found in directory. Removing.", s);
+ el.ParentNode.RemoveChild(el);
+ _removed++;
+ }
+ }
+ foreach (string s in directoryFiles.Keys)
+ {
+ if (!projectSourceFiles.Contains(s))
+ {
+ Log(Level.Verbose, "File {0} not found in project. Adding.", s);
+ XmlElement el = doc.CreateElement("File");
+ el.SetAttribute("RelPath", s);
+ if (subType != null)
+ el.SetAttribute("SubType", subType);
+ el.SetAttribute("BuildAction", buildAction);
+ filesInclude.AppendChild(el);
+ _added++;
+ }
+ }
+ }
+
+ private void ProcessMSBuildProject(XmlDocument doc)
+ {
+ SyncProjectItem(doc, "Compile", "Code", _relativeSourceFiles);
+ SyncProjectItem(doc, "EmbeddedResource", null, _relativeResourceFiles);
+ }
+
+ private void SyncProjectItem(XmlDocument doc, string type, string subType, Hashtable directoryFiles)
+ {
+ string msbuildNamespace = "http://schemas.microsoft.com/developer/msbuild/2003";
+
+ Hashtable projectSourceFiles = new Hashtable();
+ XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
+ mgr.AddNamespace("msb", msbuildNamespace);
+
+ XmlElement itemGroup = null;
+
+ foreach (XmlElement el in doc.SelectNodes("//msb:" + type, mgr))
+ {
+ string name = el.GetAttribute("Include");
+ projectSourceFiles[name] = el;
+
+ if (itemGroup == null)
+ itemGroup = (XmlElement)el.ParentNode;
+ }
+
+ if (itemGroup == null)
+ {
+ if (directoryFiles.Count > 0)
+ return;
+ XmlNode importNode = doc.SelectSingleNode("//msb:Import", mgr);
+ if (importNode == null)
+ throw new Exception("No <Import> node in project.");
+
+ itemGroup = doc.CreateElement("ItemGroup", msbuildNamespace);
+
+ doc.DocumentElement.InsertBefore(itemGroup, importNode);
+ }
+
+ foreach (string s in projectSourceFiles.Keys)
+ {
+ if (!directoryFiles.Contains(s))
+ {
+ XmlElement el = (XmlElement)projectSourceFiles[s];
+ Log(Level.Verbose, "File {0} not found in directory. Removing.", s);
+ el.ParentNode.RemoveChild(el);
+ _removed++;
+ }
+ }
+ foreach (string s in directoryFiles.Keys)
+ {
+ if (!projectSourceFiles.Contains(s))
+ {
+ Log(Level.Verbose, "File {0} not found in project. Adding.", s);
+ XmlElement el = doc.CreateElement(type, msbuildNamespace);
+ el.SetAttribute("Include", s);
+ itemGroup.AppendChild(el);
+ _added++;
+ }
+ }
+ }
+ }
+}
diff --git a/tools/UpdateBuildNumber.cs b/tools/UpdateBuildNumber.cs
new file mode 100644
index 0000000..76144e4
--- /dev/null
+++ b/tools/UpdateBuildNumber.cs
@@ -0,0 +1,209 @@
+using System;
+using System.Collections;
+using System.Text;
+using System.IO;
+using System.Xml;
+using System.Text.RegularExpressions;
+using System.Diagnostics;
+
+namespace UpdateBuildNumber
+{
+ class Program
+ {
+ static int GetSubversionRevision(string workingDir)
+ {
+ string[] svnDirs = { ".svn", "_svn" };
+
+ // try to determine the revision without spawning external EXE
+
+ foreach (string wd in svnDirs)
+ {
+ string dir = Path.Combine(workingDir, wd);
+ if (!Directory.Exists(dir))
+ continue;
+
+
+ string f = Path.Combine(dir, "entries");
+
+ // pre-1.4 XML format
+ try
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.Load(f);
+
+ foreach (XmlElement el in doc.DocumentElement.ChildNodes)
+ {
+ if (el.GetAttribute("name") == String.Empty)
+ {
+ return Convert.ToInt32(el.GetAttribute("revision"));
+ }
+ }
+ }
+ catch
+ {
+ // ignore errors
+ }
+
+ try
+ {
+ // subversion 1.4 format
+ using (StreamReader sr = File.OpenText(f))
+ {
+ string version = sr.ReadLine().Trim();
+ if (version == "8")
+ {
+ if (sr.ReadLine().Trim() == "")
+ {
+ if (sr.ReadLine().Trim() == "dir")
+ {
+ string rev = sr.ReadLine().Trim();
+ return Convert.ToInt32(rev);
+ }
+ }
+ }
+ }
+ }
+ catch
+ {
+ }
+ }
+
+ try
+ {
+ using (Process p = new Process())
+ {
+ // Console.WriteLine("Spawning 'svnversion' in {0}", workingDir);
+ p.StartInfo.WorkingDirectory = workingDir;
+ p.StartInfo.UseShellExecute = false;
+ p.StartInfo.Arguments = ".";
+ p.StartInfo.RedirectStandardOutput = true;
+ p.StartInfo.FileName = "svnversion";
+ p.StartInfo.CreateNoWindow = true;
+ p.Start();
+ p.WaitForExit();
+ if (p.ExitCode == 0)
+ {
+ StringBuilder digits = new StringBuilder();
+ string line = p.StandardOutput.ReadLine();
+ foreach (char c in line)
+ {
+ if (!Char.IsDigit(c))
+ break;
+
+ digits.Append(c);
+ }
+
+ if (digits.Length > 0)
+ return Convert.ToInt32(digits.ToString());
+ else
+ return 0;
+ }
+ else
+ {
+ throw new Exception("Process 'svnversion' has exited with error exit code: " + p.ExitCode);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new Exception("Cannot determine working copy revision.", ex);
+ }
+ }
+
+ static int Main(string[] args)
+ {
+ if (args.Length != 3)
+ {
+ Console.WriteLine("USAGE: UpdateBuildNumber versionFile assemblyInfoFile actualVersionFile");
+ Console.WriteLine();
+ Console.WriteLine("Scans for [assembly: AssemblyVersion(*)] in the assemblyInfoFile");
+ Console.WriteLine("and updates it to the version number found in versionFile.");
+ Console.WriteLine("If the last component of the version number is zero, the tool");
+ Console.WriteLine("replaces it with the Subversion revision number.");
+ return 1;
+
+ }
+
+ try
+ {
+ string versionFile = args[0];
+ string assemblyInfoFile = args[1];
+ string actualVersionFile = args[2];
+ string versionString;
+
+ using (StreamReader sr = new StreamReader(versionFile))
+ {
+ versionString = sr.ReadLine();
+ }
+ string[] versionParts = versionString.Split('.');
+ if (versionParts.Length != 4)
+ throw new Exception("Invalid version number in " + versionFile);
+
+ if (versionParts[3] == "*")
+ {
+ versionParts[3] = GetSubversionRevision(Path.GetDirectoryName(Path.GetFullPath(versionFile))).ToString();
+ }
+
+ string newVersionString = String.Join(".", versionParts);
+
+ bool modified = false;
+ ArrayList lines = new ArrayList();
+ if (File.Exists(assemblyInfoFile))
+ {
+ using (StreamReader sr = new StreamReader(assemblyInfoFile, Encoding.Default))
+ {
+ string line;
+
+ while ((line = sr.ReadLine()) != null)
+ {
+ if (line.IndexOf("AssemblyVersion(") >= 0)
+ {
+ string newLine = "[assembly: AssemblyVersion(\"" + newVersionString + "\")]";
+ if (newLine != line)
+ {
+ modified = true;
+ line = newLine;
+ }
+ }
+ lines.Add(line);
+ }
+ }
+ }
+ else
+ {
+ lines.Add("// do not modify this file. It will be automatically regenerated");
+ lines.Add("// based on the version number saved in '" + versionFile + "'");
+ lines.Add("using System.Reflection;");
+ lines.Add("[assembly: AssemblyVersion(\"" + newVersionString + "\")]");
+ modified = true;
+ }
+
+ if (modified)
+ {
+ Console.WriteLine("Build number changed to '" + newVersionString + "'. Updating " + assemblyInfoFile + "'.");
+ using (StreamWriter sw = new StreamWriter(assemblyInfoFile, false, Encoding.Default))
+ {
+ foreach (string line in lines)
+ {
+ sw.WriteLine(line);
+ }
+ }
+ }
+ else
+ {
+ Console.WriteLine("Build number in '" + assemblyInfoFile + "' is up-to-date.");
+ }
+ using (StreamWriter sw = new StreamWriter(actualVersionFile, false, Encoding.Default))
+ {
+ sw.WriteLine(newVersionString);
+ }
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("ERROR: {0}", ex);
+ return 1;
+ }
+ }
+ }
+}
diff --git a/tools/VS2005Snippets/CSharpLogger.snippet b/tools/VS2005Snippets/CSharpLogger.snippet
new file mode 100644
index 0000000..8fe5ef1
--- /dev/null
+++ b/tools/VS2005Snippets/CSharpLogger.snippet
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
+ <CodeSnippet Format="1.0.0">
+ <Header>
+ <Title>Add NLog Logger to a class</Title>
+ <Author>NLog Project</Author>
+ <Description>Add Logger creation statement to a class.</Description>
+ <Shortcut>nlogger</Shortcut>
+ <SnippetTypes>
+ <SnippetType>Expansion</SnippetType>
+ </SnippetTypes>
+ </Header>
+ <Snippet>
+ <Declarations>
+ <Literal Editable="false">
+ <ID>Logger</ID>
+ <Function>SimpleTypeName(NLog.Logger)</Function>
+ </Literal>
+ <Literal Editable="false">
+ <ID>LogManager</ID>
+ <Function>SimpleTypeName(NLog.LogManager)</Function>
+ </Literal>
+ </Declarations>
+ <Code Language="csharp">
+ <![CDATA[private static $Logger$ logger = $LogManager$.GetCurrentClassLogger();]]>
+ </Code>
+ </Snippet>
+ </CodeSnippet>
+</CodeSnippets>
\ No newline at end of file
diff --git a/tools/VS2005Snippets/VBLogger.snippet b/tools/VS2005Snippets/VBLogger.snippet
new file mode 100644
index 0000000..538ccce
--- /dev/null
+++ b/tools/VS2005Snippets/VBLogger.snippet
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
+ <CodeSnippet Format="1.0.0">
+ <Header>
+ <Title>Add NLog Logger to a class</Title>
+ <Author>NLog Project</Author>
+ <Description>Add Logger creation statement to a class.</Description>
+ <Shortcut>nlogger</Shortcut>
+ <SnippetTypes>
+ <SnippetType>Expansion</SnippetType>
+ </SnippetTypes>
+ </Header>
+ <Snippet>
+ <Declarations>
+ </Declarations>
+ <Code Language="vb">
+ <![CDATA[Private logger As NLog.Logger = NLog.LogManager.GetCurrentClassLogger()]]>
+ </Code>
+ </Snippet>
+ </CodeSnippet>
+</CodeSnippets>
diff --git a/tools/VS2005Snippets/VJSharpLogger.snippet b/tools/VS2005Snippets/VJSharpLogger.snippet
new file mode 100644
index 0000000..ec82010
--- /dev/null
+++ b/tools/VS2005Snippets/VJSharpLogger.snippet
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
+ <CodeSnippet Format="1.0.0">
+ <Header>
+ <Title>Add NLog Logger to a class</Title>
+ <Author>NLog Project</Author>
+ <Description>Add Logger creation statement to a class.</Description>
+ <Shortcut>nlogger</Shortcut>
+ <SnippetTypes>
+ <SnippetType>Expansion</SnippetType>
+ </SnippetTypes>
+ </Header>
+ <Snippet>
+ <Declarations>
+ <Literal Editable="false">
+ <ID>Logger</ID>
+ <Function>SimpleTypeName(NLog.Logger)</Function>
+ </Literal>
+ <Literal Editable="false">
+ <ID>LogManager</ID>
+ <Function>SimpleTypeName(NLog.LogManager)</Function>
+ </Literal>
+ </Declarations>
+ <Code Language="vjsharp">
+ <![CDATA[private static $Logger$ logger = $LogManager$.GetCurrentClassLogger();]]>
+ </Code>
+ </Snippet>
+ </CodeSnippet>
+</CodeSnippets>
diff --git a/tools/VS2005Templates/ItemTemplates/ConsoleNLogConfig/MyTemplate.vstemplate b/tools/VS2005Templates/ItemTemplates/ConsoleNLogConfig/MyTemplate.vstemplate
new file mode 100644
index 0000000..e33d245
--- /dev/null
+++ b/tools/VS2005Templates/ItemTemplates/ConsoleNLogConfig/MyTemplate.vstemplate
@@ -0,0 +1,19 @@
+<VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
+ <TemplateData>
+ <DefaultName>NLog.config</DefaultName>
+ <Name>Console NLog Configuration File</Name>
+ <Description>Console NLog configuration file</Description>
+ <ProjectType>$projecttype$</ProjectType>
+ <ProjectSubType>$projectsubtype$</ProjectSubType>
+ <SortOrder>10</SortOrder>
+ <Icon>__TemplateIcon.ico</Icon>
+ </TemplateData>
+ <TemplateContent>
+ <References>
+ <Reference>
+ <Assembly>NLog</Assembly>
+ </Reference>
+ </References>
+ <ProjectItem SubType="" TargetFileName="NLog.config" ReplaceParameters="true">NLog.config</ProjectItem>
+ </TemplateContent>
+</VSTemplate>
diff --git a/tools/VS2005Templates/ItemTemplates/ConsoleNLogConfig/NLog.config b/tools/VS2005Templates/ItemTemplates/ConsoleNLogConfig/NLog.config
new file mode 100644
index 0000000..1798e72
--- /dev/null
+++ b/tools/VS2005Templates/ItemTemplates/ConsoleNLogConfig/NLog.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="console" xsi:type="Console" layout="${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="console" />
+ </rules>
+</nlog>
diff --git a/tools/VS2005Templates/ItemTemplates/ConsoleNLogConfig/__TemplateIcon.ico b/tools/VS2005Templates/ItemTemplates/ConsoleNLogConfig/__TemplateIcon.ico
new file mode 100644
index 0000000..7ab089a
Binary files /dev/null and b/tools/VS2005Templates/ItemTemplates/ConsoleNLogConfig/__TemplateIcon.ico differ
diff --git a/tools/VS2005Templates/ItemTemplates/EmptyNLogConfig/MyTemplate.vstemplate b/tools/VS2005Templates/ItemTemplates/EmptyNLogConfig/MyTemplate.vstemplate
new file mode 100644
index 0000000..c186f7e
--- /dev/null
+++ b/tools/VS2005Templates/ItemTemplates/EmptyNLogConfig/MyTemplate.vstemplate
@@ -0,0 +1,19 @@
+<VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
+ <TemplateData>
+ <DefaultName>NLog.config</DefaultName>
+ <Name>Empty NLog Configuration File</Name>
+ <Description>Empty NLog configuration file</Description>
+ <ProjectType>$projecttype$</ProjectType>
+ <ProjectSubType>$projectsubtype$</ProjectSubType>
+ <SortOrder>10</SortOrder>
+ <Icon>__TemplateIcon.ico</Icon>
+ </TemplateData>
+ <TemplateContent>
+ <References>
+ <Reference>
+ <Assembly>NLog</Assembly>
+ </Reference>
+ </References>
+ <ProjectItem TargetFileName="NLog.config" ReplaceParameters="true">NLog.config</ProjectItem>
+ </TemplateContent>
+</VSTemplate>
diff --git a/tools/VS2005Templates/ItemTemplates/EmptyNLogConfig/NLog.config b/tools/VS2005Templates/ItemTemplates/EmptyNLogConfig/NLog.config
new file mode 100644
index 0000000..9ddfc96
--- /dev/null
+++ b/tools/VS2005Templates/ItemTemplates/EmptyNLogConfig/NLog.config
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ </targets>
+
+ <rules>
+ </rules>
+</nlog>
diff --git a/tools/VS2005Templates/ItemTemplates/EmptyNLogConfig/__TemplateIcon.ico b/tools/VS2005Templates/ItemTemplates/EmptyNLogConfig/__TemplateIcon.ico
new file mode 100644
index 0000000..7ab089a
Binary files /dev/null and b/tools/VS2005Templates/ItemTemplates/EmptyNLogConfig/__TemplateIcon.ico differ
diff --git a/tools/VS2005Templates/ItemTemplates/TypicalNLogConfig/MyTemplate.vstemplate b/tools/VS2005Templates/ItemTemplates/TypicalNLogConfig/MyTemplate.vstemplate
new file mode 100644
index 0000000..e56bedd
--- /dev/null
+++ b/tools/VS2005Templates/ItemTemplates/TypicalNLogConfig/MyTemplate.vstemplate
@@ -0,0 +1,19 @@
+<VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
+ <TemplateData>
+ <DefaultName>NLog.config</DefaultName>
+ <Name>Typical NLog Configuration File</Name>
+ <Description>Typical NLog configuration file</Description>
+ <ProjectType>$projecttype$</ProjectType>
+ <ProjectSubType>$projectsubtype$</ProjectSubType>
+ <SortOrder>10</SortOrder>
+ <Icon>__TemplateIcon.ico</Icon>
+ </TemplateData>
+ <TemplateContent>
+ <References>
+ <Reference>
+ <Assembly>NLog</Assembly>
+ </Reference>
+ </References>
+ <ProjectItem SubType="" TargetFileName="NLog.config" ReplaceParameters="true">NLog.config</ProjectItem>
+ </TemplateContent>
+</VSTemplate>
diff --git a/tools/VS2005Templates/ItemTemplates/TypicalNLogConfig/NLog.config b/tools/VS2005Templates/ItemTemplates/TypicalNLogConfig/NLog.config
new file mode 100644
index 0000000..2c7b208
--- /dev/null
+++ b/tools/VS2005Templates/ItemTemplates/TypicalNLogConfig/NLog.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="file" xsi:type="File" fileName="${basedir}/log.txt" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="file" />
+ </rules>
+</nlog>
diff --git a/tools/VS2005Templates/ItemTemplates/TypicalNLogConfig/__TemplateIcon.ico b/tools/VS2005Templates/ItemTemplates/TypicalNLogConfig/__TemplateIcon.ico
new file mode 100644
index 0000000..7ab089a
Binary files /dev/null and b/tools/VS2005Templates/ItemTemplates/TypicalNLogConfig/__TemplateIcon.ico differ
diff --git a/tools/generate_overloads.pl b/tools/generate_overloads.pl
new file mode 100644
index 0000000..76c5421
--- /dev/null
+++ b/tools/generate_overloads.pl
@@ -0,0 +1,195 @@
+ at levels = ('Log', 'Trace','Debug','Info','Warn','Error','Fatal');
+ at clitypes = ('System.Boolean','System.Char','System.Byte','System.String','System.Int32','System.Int64','System.Single','System.Double','System.Decimal','System.Object');
+ at nonclstypes = ('System.SByte','System.UInt32','System.UInt64');
+
+$loggercs = "../src/NLog/Logger.cs";
+
+open(IN, "<$loggercs");
+open(OUT, ">$loggercs.tmp");
+while (<IN>)
+{
+ print OUT;
+ last if (m/the following code has been automatically generated by a PERL/);
+}
+
+for $level (@levels) {
+
+ if ($level eq "Log") {
+ $level2 = "level";
+ $level3 = "specified";
+ $isenabled = "IsEnabled(level)";
+ $arg0 = "LogLevel level, ";
+ $param0 = qq!\n /// <param name="level">the log level.</param>!;
+ } else {
+ $level2 = "LogLevel.$level";
+ $level3 = "<c>$level</c>";
+ $isenabled = "Is${level}Enabled";
+ $arg0 = "";
+ $param0 = "";
+ }
+
+
+ print OUT <<EOT;
+
+ #region $level() overloads
+
+ /// <overloads>
+ /// Writes the diagnostic message at the $level3 level using the specified format provider and format parameters.
+ /// </overloads>
+ /// <summary>
+ /// Writes the diagnostic message at the $level3 level.
+ /// </summary>$param0
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ public void $level(${arg0}string message) {
+ if ($isenabled)
+ WriteToTargets($level2, message);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the $level3 level.
+ /// </summary>$param0
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void $level(${arg0}object obj) {
+ if ($isenabled)
+ WriteToTargets($level2, "{0}", new object[] { obj } );
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the $level3 level.
+ /// </summary>$param0
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="obj">A <see langword="object" /> to be written.</param>
+ public void $level(${arg0}IFormatProvider formatProvider, object obj) {
+ if ($isenabled)
+ WriteToTargets($level2, formatProvider, "{0}", new object[] { obj }, null);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message and exception at the $level3 level.
+ /// </summary>$param0
+ /// <param name="message">A <see langword="string" /> to be written.</param>
+ /// <param name="exception">An exception to be logged.</param>
+ public void ${level}Exception(${arg0}string message, Exception exception) {
+ if ($isenabled)
+ WriteToTargets($level2, null, message, null, exception);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the $level3 level using the specified parameters and formatting them with the supplied format provider.
+ /// </summary>$param0
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void $level(${arg0}IFormatProvider formatProvider, string message, params object[] args) {
+ if ($isenabled)
+ WriteToTargets($level2, formatProvider, message, args, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the $level3 level using the specified parameters.
+ /// </summary>$param0
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="args">Arguments to format.</param>
+ public void $level(${arg0}string message, params object[] args) {
+ if ($isenabled)
+ WriteToTargets($level2, message, args);
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the $level3 level using the specified parameters.
+ /// </summary>$param0
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ public void $level(${arg0}string message, System.Object arg1, System.Object arg2) {
+ if ($isenabled)
+ WriteToTargets($level2, message, new object[] { arg1, arg2 });
+ }
+
+ /// <summary>
+ /// Writes the diagnostic message at the $level3 level using the specified parameters.
+ /// </summary>$param0
+ /// <param name="message">A <see langword="string" /> containing format items.</param>
+ /// <param name="arg1">First argument to format.</param>
+ /// <param name="arg2">Second argument to format.</param>
+ /// <param name="arg3">Third argument to format.</param>
+ public void $level(${arg0}string message, System.Object arg1, System.Object arg2, System.Object arg3) {
+ if ($isenabled)
+ WriteToTargets($level2, message, new object[] { arg1, arg2, arg3 });
+ }
+EOT
+ for $t (@clitypes) {
+ print OUT <<EOT;
+ /// <summary>
+ /// Writes the diagnostic message at the $level3 level using the specified <see cref="T:$t" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>$param0
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:$t" /> argument to format.</param>
+ public void $level(${arg0}IFormatProvider formatProvider, string message, $t argument) {
+ if ($isenabled)
+ WriteToTargets($level2, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the $level3 level using the specified <see cref="T:$t" /> as a parameter.
+ /// </summary>$param0
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:$t" /> argument to format.</param>
+ public void $level(${arg0}string message, $t argument) {
+ if ($isenabled)
+ WriteToTargets($level2, message, new object[] { argument });
+ }
+EOT
+ }
+ for $t (@nonclstypes) {
+ print OUT <<EOT;
+ /// <summary>
+ /// Writes the diagnostic message at the $level3 level using the specified <see cref="T:$t" /> as a parameter and formatting it with the supplied format provider.
+ /// </summary>$param0
+ /// <param name="formatProvider">An IFormatProvider that supplies culture-specific formatting information.</param>
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:$t" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void $level(${arg0}IFormatProvider formatProvider, string message, $t argument) {
+ if ($isenabled)
+ WriteToTargets($level2, formatProvider, message, new object[] { argument }, null);
+ }
+ /// <summary>
+ /// Writes the diagnostic message at the $level3 level using the specified <see cref="T:$t" /> as a parameter.
+ /// </summary>$param0
+ /// <param name="message">A <see langword="string" /> containing one format item.</param>
+ /// <param name="argument">The <see cref="T:$t" /> argument to format.</param>
+ [CLSCompliant(false)]
+ public void $level(${arg0}string message, $t argument) {
+ if ($isenabled)
+ WriteToTargets($level2, message, new object[] { argument });
+ }
+EOT
+ }
+
+ print OUT <<EOT;
+
+ #endregion
+
+EOT
+
+
+}
+
+while (<IN>)
+{
+ if (m/end of generated code/)
+ {
+ print OUT;
+ last;
+ }
+}
+
+while (<IN>)
+{
+ print OUT;
+}
+close(OUT);
+close(IN);
+unlink($loggercs);
+rename("$loggercs.tmp", "$loggercs");
+
diff --git a/tools/logo/NLog.psp b/tools/logo/NLog.psp
new file mode 100644
index 0000000..a66a3cb
Binary files /dev/null and b/tools/logo/NLog.psp differ
diff --git a/tools/logo/NLog2.psp b/tools/logo/NLog2.psp
new file mode 100644
index 0000000..eb3bb38
Binary files /dev/null and b/tools/logo/NLog2.psp differ
diff --git a/tools/logo/NLog_ok.psp b/tools/logo/NLog_ok.psp
new file mode 100644
index 0000000..833162f
Binary files /dev/null and b/tools/logo/NLog_ok.psp differ
diff --git a/tools/logo/nlog_routing.ppt b/tools/logo/nlog_routing.ppt
new file mode 100644
index 0000000..6107665
Binary files /dev/null and b/tools/logo/nlog_routing.ppt differ
diff --git a/tools/nunit2report/NAnt.NUnit2ReportTasks.xml b/tools/nunit2report/NAnt.NUnit2ReportTasks.xml
new file mode 100644
index 0000000..d3c0132
--- /dev/null
+++ b/tools/nunit2report/NAnt.NUnit2ReportTasks.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0"?>
+<doc>
+ <assembly>
+ <name>NAnt.NUnit2ReportTasks</name>
+ </assembly>
+ <members>
+ <member name="T:NAnt.NUnit2ReportTasks.NUnit2ReportTask">
+ <summary>
+ A task that generates a summary HTML
+ from a set of NUnit xml report files.
+ </summary>
+ <remarks>
+ This task can generate a combined HTML report out of a
+ set of NUnit result files generated using the
+ XML Result Formatter.
+
+ By default, NUnitReport will generate the combined
+ report using the NUnitSummary.xsl file located at the
+ assembly's location, but you can specify a different
+ XSLT template to use with the <code>xslfile</code>
+ attribute.
+
+ Also, all the properties defined in the current
+ project will be passed down to the XSLT file as
+ template parameters, so you can access properties
+ such as nant.project.name, nant.version, etc.
+ </remarks>
+ <example>
+ <code><![CDATA[
+ <nunit2report
+ out="${outputdir}\TestSummary.html"
+ >
+ <fileset>
+ <includes name="${outputdir}\results.xml" />
+ </fileset>
+ </nunit2report>
+
+ ]]></code>
+ </example>
+ </member>
+ <member name="M:NAnt.NUnit2ReportTasks.NUnit2ReportTask.InitializeTask(System.Xml.XmlNode)">
+ <summary>
+ Initializes task and ensures the supplied attributes are valid.
+ </summary>
+ <param name="taskNode">Xml node used to define this task instance.</param>
+ </member>
+ <member name="M:NAnt.NUnit2ReportTasks.NUnit2ReportTask.ExecuteTask">
+ <summary>
+ This is where the work is done
+ </summary>
+ </member>
+ <member name="M:NAnt.NUnit2ReportTasks.NUnit2ReportTask.CreateSummaryXmlDoc">
+ <summary>
+ Initializes the XmlDocument instance
+ used to summarize the test results
+ </summary>
+ <returns></returns>
+ </member>
+ <member name="M:NAnt.NUnit2ReportTasks.NUnit2ReportTask.GetPropertyList">
+ <summary>
+ Builds an XsltArgumentList with all
+ the properties defined in the
+ current project as XSLT parameters.
+ </summary>
+ <returns></returns>
+ </member>
+ <member name="P:NAnt.NUnit2ReportTasks.NUnit2ReportTask.Format">
+ <summary>
+ The format of the generated report.
+ Must be "noframes" or "frames".
+ Default to "noframes".
+ </summary>
+ </member>
+ <member name="P:NAnt.NUnit2ReportTasks.NUnit2ReportTask.Language">
+ <summary>
+ The output language.
+ </summary>
+ </member>
+ <member name="P:NAnt.NUnit2ReportTasks.NUnit2ReportTask.OpenDescription">
+ <summary>
+ Open all description method. Default to "false".
+ </summary>
+ </member>
+ <member name="P:NAnt.NUnit2ReportTasks.NUnit2ReportTask.Todir">
+ <summary>
+ The directory where the files resulting from the transformation should be written to.
+ </summary>
+ </member>
+ <member name="P:NAnt.NUnit2ReportTasks.NUnit2ReportTask.OutFilename">
+ <summary>
+ Index of the Output HTML file(s).
+ Default to "index.htm".
+ </summary>
+ </member>
+ <member name="P:NAnt.NUnit2ReportTasks.NUnit2ReportTask.XmlFileSet">
+ <summary>
+ Set of XML files to use as input
+ </summary>
+ </member>
+ <member name="P:NAnt.NUnit2ReportTasks.NUnit2ReportTask.XmlSummaries">
+ <summary>
+ Set of XML files to use as input
+ </summary>
+ </member>
+ </members>
+</doc>
diff --git a/tools/nunit2report/NUnit-Frame.xsl b/tools/nunit2report/NUnit-Frame.xsl
new file mode 100644
index 0000000..c08328e
--- /dev/null
+++ b/tools/nunit2report/NUnit-Frame.xsl
@@ -0,0 +1,867 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:nunit2report="urn:my-scripts">
+
+<xsl:output method="html" indent="yes" encoding="ISO-8859-1"/>
+
+<xsl:param name="nant.filename" />
+<xsl:param name="nant.version" />
+<xsl:param name="nant.project.name" />
+<xsl:param name="nant.project.buildfile" />
+<xsl:param name="nant.project.basedir" />
+<xsl:param name="nant.project.default" />
+<xsl:param name="sys.os" />
+<xsl:param name="sys.os.platform" />
+<xsl:param name="sys.os.version" />
+<xsl:param name="sys.clr.version" />
+
+<!--
+Ts les noeuds à transformer en dossier
+//test-suite[not(child::results/test-case) and not(@time=0)]
+//Ts les noeuds Suite de tests
+//test-suite[(child::results/test-case)]
+Ts les noms des dossier à créer
+//test-suite[(child::results/test-case)]/ancestor::*[not(contains(@name,'.dll'))]/@name
+-->
+<msxsl:script language="C#" implements-prefix="nunit2report">
+
+ public string assemblie(string path) {
+
+ string[] a = path.Split('\\');
+
+ return(a[a.Length-1]);
+ }
+
+ public string TestCaseName(string path) {
+
+ string[] a = path.Split('.');
+
+ return(a[a.Length-1]);
+ }
+
+</msxsl:script>
+
+<xsl:template name="index.html">
+<html>
+ <head>
+ <title>Unit Test Results.</title>
+ </head>
+ <frameset cols="20%,80%" framespacing="0">
+ <frameset rows="30%,70%">
+ <frame src="overview-frame.html" name="packageListFrame"/>
+ <frame src="allclasses-frame.html" name="classListFrame"/>
+ </frameset>
+ <frame src="overview-summary.html" name="classFrame"/>
+ <noframes>
+ <h2>Frame Alert</h2>
+ <p>
+ This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+ </p>
+ </noframes>
+ </frameset>
+</html>
+</xsl:template>
+
+<xsl:template name="stylesheet.css">
+body {
+ font:normal 68% verdana,arial,helvetica;
+ color:#000000;
+}
+
+span.covered {
+ background: #00df00;
+ border:#9c9c9c 1px solid;
+}
+span.uncovered {
+ background: #df0000;
+ border-top:#9c9c9c 1px solid;
+ border-bottom:#9c9c9c 1px solid;
+ border-right:#9c9c9c 1px solid;
+ }
+span.ignored {
+ background: #ffff00;
+ border-top:#9c9c9c 1px solid;
+ border-bottom:#9c9c9c 1px solid;
+ border-right:#9c9c9c 1px solid;
+}
+
+td {
+ FONT-SIZE: 68%;
+ BORDER-BOTTOM: #dcdcdc 1px solid;
+ BORDER-RIGHT: #dcdcdc 1px solid;
+}
+p {
+ line-height:1.5em;
+ margin-top:0.5em;
+ margin-bottom:1.0em;
+}
+h1 {
+ MARGIN: 0px 0px 5px;
+ FONT: 165% verdana,arial,helvetica;
+}
+h2 {
+ MARGIN-TOP: 1em;
+ MARGIN-BOTTOM: 0.5em;
+ FONT: bold 125% verdana,arial,helvetica;
+}
+h3 {
+ MARGIN-BOTTOM: 0.5em;
+ FONT: bold 115% verdana,arial,helvetica;
+}
+h4 {
+ MARGIN-BOTTOM: 0.5em;
+ FONT: bold 100% verdana,arial,helvetica;
+}
+h5 {
+ MARGIN-BOTTOM: 0.5em;
+ FONT: bold 100% verdana,arial,helvetica
+}
+h6 {
+ MARGIN-BOTTOM: 0.5em;
+ FONT: bold 100% verdana,arial,helvetica
+}
+.Error {
+ font-weight:bold;
+}
+.Failure {
+ font-weight:bold;
+ color:red;
+}
+.Ignored {
+ font-weight:bold;
+}
+.FailureDetail {
+ font-size: -1;
+ padding-left: 2.0em;
+ background:#cdcdcd;
+}
+.Pass {
+ padding-left:2px;
+}
+.TableHeader {
+ background: #efefef;
+ color: #000;
+ font-weight: bold;
+ horizontal-align: center;
+}
+a:visited {
+ color: #0000ff;
+}
+a {
+ color: #0000ff;
+}
+a:active {
+ color: #800000;
+}
+a.summarie {
+ color:#000;
+ text-decoration: none;
+}
+a.summarie:active {
+ color:#000;
+ text-decoration: none;
+}
+a.summarie:visited {
+ color:#000;
+ text-decoration: none;
+}
+.description {
+ margin-top:1px;
+ padding:3px;
+ background-color:#dcdcdc;
+ color:#000;
+ font-weight:normal;
+}
+.method{
+ color:#000;
+ font-weight:normal;
+ padding-left:5px;
+}
+a.method{
+ text-decoration: none;
+ color:#000;
+ font-weight:normal;
+ padding-left:5px;
+}
+a.Failure {
+ font-weight:bold;
+ color:red;
+ text-decoration: none;
+}
+a.Failure:visited {
+ font-weight:bold;
+ color:red;
+ text-decoration: none;
+}
+a.Failure:active {
+ font-weight:bold;
+ color:red;
+ text-decoration: none;
+}
+a.error {
+ font-weight:bold;
+ color:red;
+}
+a.error:visited {
+ font-weight:bold;
+ color:red;
+}
+a.error:active {
+ font-weight:bold;
+ color:red;
+ /*text-decoration: none;
+ padding-left:5px;*/
+}
+a.ignored {
+ font-weight:bold;
+ text-decoration: none;
+ padding-left:5px;
+}
+a.ignored:visited {
+ font-weight:bold;
+ text-decoration: none;
+ padding-left:5px;
+}
+a.ignored:active {
+ font-weight:bold;
+ text-decoration: none;
+ padding-left:5px;
+}
+</xsl:template>
+
+
+<!--
+ Creates an html file that contains a link to all package-summary.html files on
+ each package existing on testsuites.
+ @bug there will be a problem here, I don't know yet how to handle unnamed package :(
+-->
+<xsl:template name="all.packages">
+ <html>
+ <head>
+ <title>All Unit Test Packages</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2><a href="overview-summary.html" id=":i18n:Home" target="classFrame">Home</a></h2>
+
+ <h2>Assemblies</h2>
+ <!-- //test-results/@name -->
+ <table width="100%">
+ <tr>
+ <td nowrap="nowrap">
+ <a target="classFrame" href="overview-summary.html"><xsl:value-of select="nunit2report:assemblie(@name)"/></a>
+ </td>
+ </tr>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template name="overview.packages">
+ <html>
+ <head>
+ <title>Unit Test Results: Summary</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ <xsl:call-template name="toggle"/>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('allclasses-frame.html','classListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <xsl:call-template name="envinfo"/>
+
+ <h2 id=":i18n:Summary">Summary</h2>
+ <xsl:variable name="runCount" select="@total"/><!-- testCount -->
+ <!-- <xsl:variable name="errorCount" select="@not-run"/>
+ <xsl:variable name="failureCount" select="@failures"/>-->
+
+ <xsl:variable name="failureCount" select="@failures"/>
+ <xsl:variable name="ignoreCount" select="@not-run"/>
+ <xsl:variable name="total" select="$runCount + $ignoreCount + $failureCount"/>
+
+ <xsl:variable name="timeCount" select="translate(test-suite/@time,',','.')"/>
+
+ <!-- <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>-->
+ <xsl:variable name="successRate" select="$runCount div $total"/>
+
+ <table border="0" cellpadding="2" cellspacing="0" width="95%" style="border: #dcdcdc 1px solid;">
+ <xsl:call-template name="summaryHeader"/>
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$failureCount > 0">Failure</xsl:when>
+ <xsl:when test="$ignoreCount > 0">Error</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><xsl:value-of select="$runCount"/></td>
+ <td><xsl:value-of select="$failureCount"/></td>
+ <td><xsl:value-of select="$ignoreCount"/></td>
+ <td width="280px">
+ <xsl:call-template name="display-percent">
+ <xsl:with-param name="value" select="$successRate"/>
+ </xsl:call-template>
+ <xsl:if test="round($runCount * 200 div $total )!=0">
+ <span class="covered">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($runCount * 200 div $total )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ <xsl:if test="round($ignoreCount * 200 div $total )!=0">
+ <span class="ignored">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($ignoreCount * 200 div $total )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ <xsl:if test="round($failureCount * 200 div $total )!=0">
+ <span class="uncovered">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($failureCount * 200 div $total )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ </td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ <span id=":i18n:Note">Note</span>: <i id=":i18n:failures">failures</i> <span id=":i18n:anticipated">are anticipated and checked for with assertions while</span> <i id=":i18n:errors">errors</i> <span id=":i18n:unanticipated">are unanticipated.</span>
+
+ <h2 id=":i18n:TestSuiteSummary">TestSuite Summary</h2>
+ <table border="0" cellpadding="2" cellspacing="0" width="95%">
+ <xsl:call-template name="packageSummaryHeader"/>
+ <!-- list all packages recursively -->
+ <xsl:for-each select="//test-suite[(child::results/test-case)]">
+ <xsl:sort select="@name"/>
+ <!--<xsl:variable name="testCount2" select="count(child::results/test-case)"/>
+ <xsl:variable name="errorCount2" select="count(child::results/test-case[@executed='False'])"/>
+ <xsl:variable name="failureCount2" select="count(child::results/test-case[@success='False'])"/>
+ <xsl:variable name="timeCount2" select="translate(@time,',','.')"/>-->
+
+ <xsl:variable name="runCount2" select="count(child::results/test-case)"/>
+ <xsl:variable name="errorCount2" select="count(child::results/test-case[@executed='False'])"/>
+ <xsl:variable name="failureCount2" select="count(child::results/test-case[@success='False'])"/>
+ <xsl:variable name="testCount2" select="$runCount2 + $errorCount2 + $failureCount2"/>
+ <xsl:variable name="timeCount2" select="translate(@time,',','.')"/>
+
+ <!-- write a summary for the package -->
+ <tr valign="top">
+ <!-- set a nice color depending if there is an error/failure -->
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$failureCount2 > 0">Failure</xsl:when>
+ <xsl:when test="$errorCount2 > 0"> Error</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td>
+
+ <!-- ******************************************************* -->
+ <!-- Rajout chemin http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/htm/xpath_hdi_2_5veb.asp -->
+ <!-- ******************************************************* -->
+ <xsl:variable name="path.dir">
+ <xsl:for-each select="ancestor-or-self::*"><xsl:if test="not(contains(@name,'.dll')) and not(name()='results' or name()='testsummary')"><xsl:value-of select="concat(@name,'/')"/></xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="$path.dir"/>
+ <xsl:value-of select="@name"/>.html</xsl:attribute>
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$failureCount2 > 0">Failure</xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+<!-- ******************************************************* -->
+ <td width="15%" align="right">
+ <xsl:variable name="successRate2" select="$runCount2 div $testCount2"/>
+ <b>
+ <xsl:call-template name="display-percent">
+ <xsl:with-param name="value" select="$successRate2"/>
+ </xsl:call-template>
+ </b>
+ </td>
+ <td width="40%" height="9px">
+ <xsl:if test="round($runCount2 * 200 div $testCount2 )!=0">
+ <span class="covered">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($runCount2 * 200 div $testCount2 )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ <xsl:if test="round($errorCount2 * 200 div $testCount2 )!=0">
+ <span class="ignored">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($errorCount2 * 200 div $testCount2 )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ <xsl:if test="round($failureCount2 * 200 div $testCount2 )!=0">
+ <span class="uncovered">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($failureCount2 * 200 div $testCount2 )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ </td>
+<!-- ******************************************************* -->
+ <td><xsl:value-of select="$runCount2"/>
+ </td>
+ <td><xsl:value-of select="$errorCount2"/></td>
+ <td><xsl:value-of select="$failureCount2"/></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount2"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+
+ </body>
+ </html>
+</xsl:template>
+
+<!--
+ Creates an all-classes.html file that contains a link to all package-summary.html
+ on each class.
+-->
+<xsl:template name="all.classes" >
+ <html>
+ <head>
+ <title>All Unit Test Classes</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2>Test Suite</h2>
+ <table border="0" width="95%">
+ <!-- list all packages recursively -->
+ <xsl:for-each select="//test-suite[(child::results/test-case)]">
+ <xsl:sort select="@name"/>
+
+ <xsl:variable name="errorCount" select="count(child::results/test-case[@executed='False'])"/>
+ <xsl:variable name="failureCount" select="count(child::results/test-case[@success='False'])"/>
+
+ <xsl:variable name="path.dir">
+ <xsl:for-each select="ancestor-or-self::*"><xsl:if test="not(contains(@name,'.dll')) and not(name()='results' or name()='testsummary')"><xsl:value-of select="concat(@name,'/')"/></xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <!-- write a summary for the package -->
+ <tr nowrap="nowrap">
+ <td>
+ <a target="classFrame" >
+ <xsl:attribute name="href">
+ <xsl:value-of select="$path.dir"/>
+ <xsl:value-of select="@name"/>.html</xsl:attribute>
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+
+ </body>
+ </html>
+</xsl:template>
+
+<!-- create the link to the stylesheet based on the package name -->
+<xsl:template name="create.stylesheet.link">
+ <xsl:param name="package.name"/>
+ <link rel="stylesheet" type="text/css" title="Style"><xsl:attribute name="href"><xsl:if test="not($package.name = 'unnamed package')"><xsl:call-template name="path"><xsl:with-param name="path" select="$package.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></link>
+</xsl:template>
+
+
+<!--
+ transform string like a.b.c to ../../../
+ @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+ <xsl:param name="path"/>
+ <xsl:if test="contains($path,'.')">
+ <xsl:text>../</xsl:text>
+ <xsl:call-template name="path">
+ <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="not(contains($path,'.')) and not($path = '')">
+ <xsl:text>../</xsl:text>
+ </xsl:if>
+</xsl:template>
+
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+<xsl:param name="path"/>
+
+<h1><span id=":i18n:UnitTestsResults">Unit Tests Results</span> - <xsl:value-of select="$nant.project.name"/></h1>
+ <table width="100%">
+ <tr>
+ <td align="left">
+ <span id=":i18n:GeneratedBy">Generated by</span> <a target="_blank" href="http://sourceforge.net/projects/nunit2report/">NUnit2Report</a> : <xsl:value-of select="/testsummary/test-results/@date"/> - <xsl:value-of select="concat(/testsummary/test-results/@time,' ')"/> <a href="#" onclick="javascript:Toggle('blabla')" id=":i18n:EnvironmentInformation">Environment Information</a>
+ </td>
+ <td align="right"><span id=":i18n:Designed">Designed for use with</span> <a href='http://nunit.sourceforge.net/'>NUnit</a> <span id=":i18n:and">and</span> <a href='http://nant.sourceforge.net/'>NAnt</a>.
+ </td>
+ </tr>
+ </table>
+ <hr size="1"/>
+</xsl:template>
+
+
+<xsl:template name="summaryHeader">
+ <tr valign="top" class="TableHeader">
+ <td><b id=":i18n:Tests">Tests</b></td>
+ <td><b id=":i18n:Failures">Failures</b></td>
+ <td><b id=":i18n:Errors">Errors</b></td>
+ <td><b id=":i18n:SuccessRate">Success Rate</b></td>
+ <td nowrap="nowrap"><b id=":i18n:Time">Time(s)</b></td>
+ </tr>
+</xsl:template>
+
+<!--
+ =====================================================================
+ testcase report
+ =====================================================================
+-->
+<xsl:template name="test-case">
+
+ <xsl:param name="dir.test"/>
+ <xsl:param name="summary.xml"/>
+ <xsl:param name="open.description"/>
+
+ <xsl:variable name="summaries" select="document($summary.xml)" />
+
+ <html>
+ <head>
+ <title>Unit Test for class <xsl:value-of select="./@name"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name">
+ <xsl:value-of select="$dir.test"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="toggle"/>
+ </head>
+ <body>
+ <xsl:call-template name="pageHeader">
+ <xsl:with-param name="path">
+ <xsl:value-of select="$dir.test"/>
+ </xsl:with-param>
+ </xsl:call-template>
+
+ <xsl:call-template name="envinfo"/>
+
+ <h3>Test Suite</h3>
+
+ <!-- Summary -->
+ <table border="0" cellpadding="2" cellspacing="0" width="95%">
+ <xsl:call-template name="packageSummaryHeader"/>
+
+ <!--<xsl:variable name="testCount" select="count(./results/test-case)"/>
+ <xsl:variable name="errorCount" select="count(./results/test-case[@executed='False'])"/>
+ <xsl:variable name="failureCount" select="count(./results/test-case[@success='False'])"/>
+ <xsl:variable name="timeCount" select="translate(@time,',','.')"/>-->
+
+ <xsl:variable name="testCount" select="count(./results/test-case)"/>
+ <xsl:variable name="errorCount" select="count(./results/test-case[@executed='False'])"/>
+ <xsl:variable name="failureCount" select="count(./results/test-case[@success='False'])"/>
+ <xsl:variable name="runCount" select="$testCount - $errorCount - $failureCount"/>
+ <xsl:variable name="timeCount" select="translate(@time,',','.')"/>
+
+ <!-- write a summary for the package -->
+ <tr valign="top">
+ <!-- set a nice color depending if there is an error/failure -->
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$failureCount > 0">Failure</xsl:when>
+ <xsl:when test="$errorCount > 0"> Error</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td>
+ <xsl:value-of select="@name"/>
+ </td>
+<!-- ******************************************************* -->
+ <td width="15%" align="right">
+ <xsl:variable name="successRate" select="$runCount div $testCount"/>
+ <b>
+ <xsl:call-template name="display-percent">
+ <xsl:with-param name="value" select="$successRate"/>
+ </xsl:call-template>
+ </b>
+ </td>
+ <td width="40%" height="9px">
+ <xsl:if test="round($runCount * 200 div $testCount )!=0">
+ <span class="covered">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($runCount * 200 div $testCount )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ <xsl:if test="round($errorCount * 200 div $testCount )!=0">
+ <span class="ignored">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($errorCount * 200 div $testCount )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ <xsl:if test="round($failureCount * 200 div $testCount )!=0">
+ <span class="uncovered">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($failureCount * 200 div $testCount )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ </td>
+<!-- ******************************************************* -->
+ <td><xsl:value-of select="$runCount"/>
+ </td>
+ <td><xsl:value-of select="$errorCount"/></td>
+ <td><xsl:value-of select="$failureCount"/></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ <br/>
+ <h3>Test Case</h3>
+ <table border="0" cellpadding="1" cellspacing="1" width="95%" >
+ <!-- Header -->
+ <xsl:call-template name="classesSummaryHeader"/>
+
+
+ <!-- match the testcases of this package -->
+ <xsl:for-each select="child::results/test-case">
+ <xsl:sort select="@name"/>
+ <xsl:variable name="newid" select="generate-id(@name)" />
+ <xsl:variable name="Mname" select="concat('M:', at name)" />
+
+ <xsl:variable name="result">
+ <xsl:choose>
+ <xsl:when test="./failure"><span id=":i18n:Failure">Failure</span></xsl:when>
+ <xsl:when test="./error"><span id=":i18n:Error">Error</span></xsl:when>
+ <xsl:when test="@executed='False'"><span id=":i18n:Ignored">Ignored</span></xsl:when>
+ <xsl:otherwise><span id=":i18n:Pass">Pass</span></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <tr valign="top">
+ <xsl:attribute name="class"><xsl:value-of select="$result"/></xsl:attribute>
+
+ <td width="20%">
+ <xsl:choose>
+ <xsl:when test="$summary.xml != ''">
+ <!-- Triangle image -->
+ <a class="summarie"><xsl:attribute name="href">javascript:Toggle('<xsl:value-of select="concat('M:',$newid)"/>');ToggleImage('<xsl:value-of select="concat('I:',$newid)"/>')</xsl:attribute><xsl:attribute name="id"><xsl:value-of select="concat('I:',$newid)"/></xsl:attribute>
+ <!-- Set the good triangle image -->
+ <xsl:choose>
+ <xsl:when test="$result != "Pass"">-</xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$open.description='yes'">-</xsl:when>
+ <xsl:otherwise>+</xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </a>
+ </xsl:when>
+ </xsl:choose>
+
+ <!-- If failure, you can click on the test method name and color is red -->
+ <xsl:choose>
+ <xsl:when test="$result = 'Failure' or $result = 'Error'">
+ <a style="text-decoration:none">
+ <xsl:attribute name="href">javascript:Toggle('<xsl:value-of select="$newid"/>')</xsl:attribute>
+ <xsl:attribute name="class">Failure</xsl:attribute>
+ <xsl:value-of select="nunit2report:TestCaseName(./@name)"/>
+ </a>
+ </xsl:when>
+ <xsl:when test="$result = 'Ignored'">
+ <a>
+ <xsl:attribute name="href">javascript:Toggle('<xsl:value-of select="$newid"/>')</xsl:attribute>
+ <xsl:attribute name="class">ignored</xsl:attribute>
+ <xsl:value-of select="nunit2report:TestCaseName(./@name)"/>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="class">method</xsl:attribute>
+ <xsl:value-of select="nunit2report:TestCaseName(./@name)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+<!-- *************************************** -->
+ </td>
+ <td width="65%" style="padding-left:3px" height="9px">
+ <xsl:choose>
+ <xsl:when test="$result = 'Pass'">
+ <span class="covered" style="width:200px"></span>
+ </xsl:when>
+ <xsl:when test="$result = 'Ignored'">
+ <span class="ignored" style="width:200px"></span>
+ </xsl:when>
+ <xsl:when test="$result = 'Failure' or $result = 'Error'">
+ <span class="uncovered" style="width:200px"></span>
+ </xsl:when>
+ </xsl:choose>
+<!-- ****************************** -->
+ <!-- The test method description-->
+ <xsl:choose>
+ <xsl:when test="$summary.xml != ''">
+ <div class="description">
+ <!-- Attribute id -->
+ <xsl:attribute name="id"><xsl:value-of select="concat('M:',$newid)"/></xsl:attribute>
+ <!-- Open method description if failure -->
+ <xsl:choose>
+ <xsl:when test="$result != "Pass"">
+ <xsl:attribute name="style">display:block</xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$open.description = 'yes'">
+ <xsl:attribute name="style">display:block</xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="style">display:none</xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ <!-- The description of the test method -->
+ <xsl:value-of select="normalize-space($summaries//member[@name=$Mname]/summary/text())" />
+ </div>
+ </xsl:when>
+ </xsl:choose>
+ </td>
+ <td><xsl:attribute name="id">:i18n:<xsl:value-of select="$result"/></xsl:attribute><xsl:value-of select="$result"/></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="@time"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <xsl:if test="$result != "Pass"">
+ <tr style="display: block;">
+ <xsl:attribute name="id">
+ <xsl:value-of select="$newid"/>
+ </xsl:attribute>
+ <td colspan="3" class="FailureDetail">
+ <xsl:apply-templates select="./failure"/>
+ <xsl:apply-templates select="./error"/>
+ <xsl:apply-templates select="./reason"/>
+ </td>
+ </tr>
+ </xsl:if>
+ </xsl:for-each>
+ </table>
+
+ </body>
+ </html>
+</xsl:template>
+
+<!--
+ =====================================================================
+ package summary header
+ =====================================================================
+-->
+<xsl:template name="packageSummaryHeader">
+ <tr class="TableHeader" valign="top">
+ <td width="75%" colspan="3"><b id=":i18n:Name">Name</b></td>
+ <td width="5%"><b id=":i18n:Tests">Tests</b></td>
+ <td width="5%"><b id=":i18n:Errors">Errors</b></td>
+ <td width="5%"><b id=":i18n:Failures">Failures</b></td>
+ <td width="10%" nowrap="nowrap"><b id=":i18n:Time">Time(s)</b></td>
+ </tr>
+</xsl:template>
+
+<!--
+ =====================================================================
+ classes summary header
+ =====================================================================
+-->
+<xsl:template name="classesSummaryHeader">
+ <tr class="TableHeader" valign="top">
+ <td width="85%" colspan="2"><b id=":i18n:Name">Name</b></td>
+ <td width="10%"><b id=":i18n:Status">Status</b></td>
+ <td width="5%" nowrap="nowrap"><b id=":i18n:Time">Time(s)</b></td>
+ </tr>
+</xsl:template>
+
+
+<!--
+ format a number in to display its value in percent
+ @param value the number to format
+-->
+<xsl:template name="display-time">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.000')"/>
+</xsl:template>
+
+<!--
+ format a number in to display its value in percent
+ @param value the number to format
+-->
+<xsl:template name="display-percent">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.00 %')"/>
+</xsl:template>
+
+<!--
+ =====================================================================
+ Environtment Info Report
+ =====================================================================
+-->
+<xsl:template name="envinfo">
+ <div id="blabla" style="display: none;">
+ <a name="envinfo"></a>
+ <h2 id=":i18n:EnvironmentInformation">Environment Information</h2>
+ <table border="0" cellpadding="5" cellspacing="2" width="95%">
+ <tr class="EnvInfoHeader">
+ <td id=":i18n:Property">Property</td>
+ <td id=":i18n:Value">Value</td>
+ </tr>
+ <tr class="EnvInfoRow">
+ <td id=":i18n:NAntLocation">NAnt Location</td>
+ <td><xsl:value-of select="$nant.filename"/></td>
+ </tr>
+ <tr class="EnvInfoRow">
+ <td id=":i18n:NAntVersion">NAnt Version</td>
+ <td><xsl:value-of select="$nant.version"/></td>
+ </tr>
+ <tr class="EnvInfoRow">
+ <td id=":i18n:Buildfile">Buildfile</td>
+ <td><xsl:value-of select="$nant.project.buildfile"/></td>
+ </tr>
+ <tr class="EnvInfoRow">
+ <td id=":i18n:BaseDirectory">Base Directory</td>
+ <td><xsl:value-of select="$nant.project.basedir"/></td>
+ </tr>
+ <tr class="EnvInfoRow">
+ <td id=":i18n:OperatingSystem">Operating System</td>
+ <td><xsl:value-of select="$sys.os"/></td>
+ </tr>
+ <tr class="EnvInfoRow">
+ <td id=":i18n:NETCLRVersion">.NET CLR Version</td>
+ <td><xsl:value-of select="$sys.clr.version"/></td>
+ </tr>
+ </table>
+ <hr size="1" width="95%" align="left"/>
+ </div>
+</xsl:template>
+
+<xsl:template name="toggle">
+ <script language="JavaScript"><![CDATA[
+ function Toggle(id) {
+ var element = document.getElementById(id);
+
+ if ( element.style.display == "none" )
+ element.style.display = "block";
+ else
+ element.style.display = "none";
+ }
+
+ function ToggleImage(id) {
+ var element = document.getElementById(id);
+
+ if ( element.innerText == "-" )
+ element.innerText = "+";
+ else
+ element.innerText = "-";
+ }
+ ]]></script>
+</xsl:template>
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tools/nunit2report/NUnit-NoFrame.xsl b/tools/nunit2report/NUnit-NoFrame.xsl
new file mode 100644
index 0000000..11a7134
--- /dev/null
+++ b/tools/nunit2report/NUnit-NoFrame.xsl
@@ -0,0 +1,344 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!--
+ This XSL File is based on the NUnitSummary.xsl
+ template created by Tomas Restrepo fot NAnt's NUnitReport.
+
+ Modified by Gilles Bayon (gilles.bayon at laposte.net) for use
+ with NUnit2Report.
+
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:html="http://www.w3.org/Profiles/XHTML-transitional">
+
+ <xsl:output method="html" indent="yes"/>
+ <xsl:include href="toolkit.xsl"/>
+ <xsl:preserve-space elements='a root'/>
+
+
+<!--
+ ====================================================
+ Create the page structure
+ ====================================================
+-->
+<xsl:template match="test-results">
+ <HTML>
+ <HEAD>
+ <style type="text/css">
+ body {
+ font:normal 68% verdana,arial,helvetica;
+ color:#000000;
+ }
+
+ span.covered {
+ background: #00df00;
+ border:#9c9c9c 1px solid;
+ }
+ span.uncovered {
+ background: #df0000;
+ border-top:#9c9c9c 1px solid;
+ border-bottom:#9c9c9c 1px solid;
+ border-right:#9c9c9c 1px solid;
+ }
+ span.ignored {
+ background: #ffff00;
+ border-top:#9c9c9c 1px solid;
+ border-bottom:#9c9c9c 1px solid;
+ border-right:#9c9c9c 1px solid;
+ }
+
+ td {
+ FONT-SIZE: 68%;
+ BORDER-BOTTOM: #dcdcdc 1px solid;
+ BORDER-RIGHT: #dcdcdc 1px solid;
+ }
+ p {
+ line-height:1.5em;
+ margin-top:0.5em;
+ margin-bottom:1.0em;
+ }
+ h1 {
+ MARGIN: 0px 0px 5px;
+ FONT: 165% verdana,arial,helvetica;
+ }
+ h2 {
+ MARGIN-TOP: 1em;
+ MARGIN-BOTTOM: 0.5em;
+ FONT: bold 125% verdana,arial,helvetica;
+ }
+ h3 {
+ MARGIN-BOTTOM: 0.5em;
+ FONT: bold 115% verdana,arial,helvetica;
+ }
+ h4 {
+ MARGIN-BOTTOM: 0.5em;
+ FONT: bold 100% verdana,arial,helvetica;
+ }
+ h5 {
+ MARGIN-BOTTOM: 0.5em;
+ FONT: bold 100% verdana,arial,helvetica
+ }
+ h6 {
+ MARGIN-BOTTOM: 0.5em;
+ FONT: bold 100% verdana,arial,helvetica
+ }
+ .Error {
+ font-weight:bold;
+ }
+ .Failure {
+ font-weight:bold;
+ color:red;
+ }
+ .Ignored {
+ font-weight:bold;
+ }
+ .FailureDetail {
+ font-size: -1;
+ padding-left: 2.0em;
+ background:#cdcdcd;
+ }
+ .Pass {
+ padding-left:2px;
+ }
+ .TableHeader {
+ background: #efefef;
+ color: #000;
+ font-weight: bold;
+ horizontal-align: center;
+ }
+ a:visited {
+ color: #0000ff;
+ }
+ a {
+ color: #0000ff;
+ }
+ a:active {
+ color: #800000;
+ }
+ a.summarie {
+ color:#000;
+ text-decoration: none;
+ }
+ a.summarie:active {
+ color:#000;
+ text-decoration: none;
+ }
+ a.summarie:visited {
+ color:#000;
+ text-decoration: none;
+ }
+ .description {
+ margin-top:1px;
+ padding:3px;
+ background-color:#dcdcdc;
+ color:#000;
+ font-weight:normal;
+ }
+ .method{
+ color:#000;
+ font-weight:normal;
+ padding-left:5px;
+ }
+ a.method{
+ text-decoration: none;
+ color:#000;
+ font-weight:normal;
+ padding-left:5px;
+ }
+ a.Failure {
+ font-weight:bold;
+ color:red;
+ text-decoration: none;
+ }
+ a.Failure:visited {
+ font-weight:bold;
+ color:red;
+ text-decoration: none;
+ }
+ a.Failure:active {
+ font-weight:bold;
+ color:red;
+ text-decoration: none;
+ }
+ a.error {
+ font-weight:bold;
+ color:red;
+ }
+ a.error:visited {
+ font-weight:bold;
+ color:red;
+ }
+ a.error:active {
+ font-weight:bold;
+ color:red;
+ /*text-decoration: none;
+ padding-left:5px;*/
+ }
+ a.ignored {
+ font-weight:bold;
+ text-decoration: none;
+ padding-left:5px;
+ }
+ a.ignored:visited {
+ font-weight:bold;
+ text-decoration: none;
+ padding-left:5px;
+ }
+ a.ignored:active {
+ font-weight:bold;
+ text-decoration: none;
+ padding-left:5px;
+ }
+ </style>
+ <script language="JavaScript"><![CDATA[
+ function Toggle(id) {
+ var element = document.getElementById(id);
+
+ if ( element.style.display == "none" )
+ element.style.display = "block";
+ else
+ element.style.display = "none";
+ }
+
+ function ToggleImage(id) {
+ var element = document.getElementById(id);
+
+ if ( element.innerText == "-" )
+ element.innerText = "+";
+ else
+ element.innerText = "-";
+ }
+ ]]></script>
+ </HEAD>
+ <body text="#000000" bgColor="#ffffff">
+ <a name="#top"></a>
+ <xsl:call-template name="header"/>
+
+ <!-- Summary part -->
+ <xsl:call-template name="summary"/>
+ <hr size="1" width="95%" align="left"/>
+
+ <!-- Package List part -->
+ <xsl:call-template name="packagelist"/>
+ <hr size="1" width="95%" align="left"/>
+
+ <!-- For each testsuite create the part -->
+ <xsl:call-template name="testsuites"/>
+ <hr size="1" width="95%" align="left"/>
+
+ <!-- Environment info part -->
+
+ <xsl:call-template name="envinfo"/>
+
+ </body>
+ </HTML>
+</xsl:template>
+
+
+
+ <!-- ================================================================== -->
+ <!-- Write a list of all packages with an hyperlink to the anchor of -->
+ <!-- of the package name. -->
+ <!-- ================================================================== -->
+ <xsl:template name="packagelist">
+ <h2 id=":i18n:TestSuiteSummary">TestSuite Summary</h2>
+ <table border="0" cellpadding="2" cellspacing="0" width="95%">
+ <xsl:call-template name="packageSummaryHeader"/>
+ <!-- list all packages recursively -->
+ <xsl:for-each select="//test-suite[(child::results/test-case)]">
+ <xsl:sort select="@name"/>
+ <xsl:variable name="testCount" select="count(child::results/test-case)"/>
+ <xsl:variable name="errorCount" select="count(child::results/test-case[@executed='False'])"/>
+ <xsl:variable name="failureCount" select="count(child::results/test-case[@success='False'])"/>
+ <xsl:variable name="runCount" select="$testCount - $errorCount - $failureCount"/>
+ <xsl:variable name="timeCount" select="translate(@time,',','.')"/>
+
+ <!-- write a summary for the package -->
+ <tr valign="top">
+ <!-- set a nice color depending if there is an error/failure -->
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$failureCount > 0">Failure</xsl:when>
+ <xsl:when test="$errorCount > 0"> Error</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td width="25%">
+ <a href="#{generate-id(@name)}">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$failureCount > 0">Failure</xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ <td nowrap="nowrap" width="6%" align="right">
+ <xsl:variable name="successRate" select="$runCount div $testCount"/>
+ <b>
+ <xsl:call-template name="display-percent">
+ <xsl:with-param name="value" select="$successRate"/>
+ </xsl:call-template>
+ </b>
+ </td>
+ <td width="20%" height="9px">
+ <xsl:if test="round($runCount * 200 div $testCount )!=0">
+ <span class="covered">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($runCount * 200 div $testCount )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ <xsl:if test="round($errorCount * 200 div $testCount )!=0">
+ <span class="ignored">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($errorCount * 200 div $testCount )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ <xsl:if test="round($failureCount * 200 div $testCount )!=0">
+ <span class="uncovered">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($failureCount * 200 div $testCount )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ </td>
+ <td><xsl:value-of select="$runCount"/></td>
+ <td><xsl:value-of select="$errorCount"/></td>
+ <td><xsl:value-of select="$failureCount"/></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </xsl:template>
+
+
+ <xsl:template name="testsuites">
+ <xsl:for-each select="//test-suite[(child::results/test-case)]">
+ <xsl:sort select="@name"/>
+ <!-- create an anchor to this class name -->
+ <a name="#{generate-id(@name)}"></a>
+ <h3>TestSuite <xsl:value-of select="@name"/></h3>
+
+ <table border="0" cellpadding="1" cellspacing="1" width="95%">
+ <!-- Header -->
+ <xsl:call-template name="classesSummaryHeader"/>
+
+ <!-- match the testcases of this package -->
+ <xsl:apply-templates select="results/test-case">
+ <xsl:sort select="@name" />
+ </xsl:apply-templates>
+ </table>
+ <a href="#top" id=":i18n:Backtotop">Back to top</a>
+ </xsl:for-each>
+ </xsl:template>
+
+
+ <xsl:template name="dot-replace">
+ <xsl:param name="package"/>
+ <xsl:choose>
+ <xsl:when test="contains($package,'.')"><xsl:value-of select="substring-before($package,'.')"/>_<xsl:call-template name="dot-replace"><xsl:with-param name="package" select="substring-after($package,'.')"/></xsl:call-template></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$package"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/nunit2report/Traductions.xml b/tools/nunit2report/Traductions.xml
new file mode 100644
index 0000000..02fbf28
--- /dev/null
+++ b/tools/nunit2report/Traductions.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<Traductions>
+ <Traduction lang="fr" key="UnitTestsResults">Résultats des Test Unitaires</Traduction>
+ <Traduction lang="fr" key="GeneratedBy">Généré par</Traduction>
+ <Traduction lang="fr" key="Designed">A utiliser avec</Traduction>
+ <Traduction lang="fr" key="and">et</Traduction>
+ <Traduction lang="fr" key="EnvironmentInformation">Informations environnement</Traduction>
+ <Traduction lang="fr" key="Tests">Tests</Traduction>
+ <Traduction lang="fr" key="Failures">Echecs</Traduction>
+ <Traduction lang="fr" key="Errors">Erreurs</Traduction>
+ <Traduction lang="fr" key="SuccessRate">Taux de succès</Traduction>
+ <Traduction lang="fr" key="Time">Durée (s)</Traduction>
+ <Traduction lang="fr" key="Summary">Résumé</Traduction>
+ <Traduction lang="fr" key="Name">Nom</Traduction>
+ <Traduction lang="fr" key="Status">Status</Traduction>
+ <Traduction lang="fr" key="TestSuiteSummary">Index des suites de tests</Traduction>
+ <Traduction lang="fr" key="Backtotop">Retour haut de page</Traduction>
+ <Traduction lang="fr" key="NETCLRVersion">Version .NET CLR</Traduction>
+ <Traduction lang="fr" key="OperatingSystem">Système d'exploitation</Traduction>
+ <Traduction lang="fr" key="BaseDirectory">Répertoire de base</Traduction>
+ <Traduction lang="fr" key="Buildfile">Fichier de construction</Traduction>
+ <Traduction lang="fr" key="NAntVersion">Nant Version</Traduction>
+ <Traduction lang="fr" key="NAntLocation">Répertoire Nant</Traduction>
+ <Traduction lang="fr" key="Value">Valeur</Traduction>
+ <Traduction lang="fr" key="Property">Propriété</Traduction>
+ <Traduction lang="fr" key="EnvironmentInformation">Information Environment</Traduction>
+ <Traduction lang="fr" key="anticipated">sont prévisibles et vérifiés grâce aux assertions tandis que les</Traduction>
+ <Traduction lang="fr" key="failures">Les échecs</Traduction>
+ <Traduction lang="fr" key="errors">erreurs</Traduction>
+ <Traduction lang="fr" key="unanticipated">ne sont pas anticipées.</Traduction>
+ <Traduction lang="fr" key="Note">Note</Traduction>
+ <Traduction lang="fr" key="Failure">Echec</Traduction>
+ <Traduction lang="fr" key="Error">Erreur</Traduction>
+ <Traduction lang="fr" key="Pass">Passé</Traduction>
+ <Traduction lang="fr" key="Ignored">Ignoré</Traduction>
+ <Traduction lang="fr" key="Home">Accueil</Traduction>
+</Traductions>
+
\ No newline at end of file
diff --git a/tools/nunit2report/i18n.xsl b/tools/nunit2report/i18n.xsl
new file mode 100644
index 0000000..ab393ae
--- /dev/null
+++ b/tools/nunit2report/i18n.xsl
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<xsl:stylesheet version="1.0"
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:output method="html" encoding="iso-8859-1" />
+
+<xsl:param name="lang" />
+
+ <xsl:variable name="traduc"
+ select="document('Traductions.xml')" />
+
+ <xsl:template match="text()">
+ <xsl:variable name="key"
+ select="substring-after(substring-after(../@id, ':'), ':')" />
+
+ <xsl:choose>
+ <xsl:when test="contains(../@id, 'i18n') and $lang!=''">
+ <xsl:value-of select="$traduc//Traduction[@key=$key and @lang=$lang]" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="." />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="*">
+ <xsl:copy>
+ <!-- Copy attributs <> of id -->
+ <xsl:copy-of select="@*[name() != 'id']" />
+
+ <!-- special case of id attribut -->
+ <xsl:choose>
+ <xsl:when test="contains(@id, 'i18n')">
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="@id" />
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:apply-templates select="node()" />
+ </xsl:copy>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/tools/nunit2report/toolkit.xsl b/tools/nunit2report/toolkit.xsl
new file mode 100644
index 0000000..1118a1d
--- /dev/null
+++ b/tools/nunit2report/toolkit.xsl
@@ -0,0 +1,410 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:nunit2report="urn:my-scripts">
+<xsl:param name="nant.filename" />
+<xsl:param name="nant.version" />
+<xsl:param name="nant.project.name" />
+<xsl:param name="nant.project.buildfile" />
+<xsl:param name="nant.project.basedir" />
+<xsl:param name="nant.project.default" />
+<xsl:param name="sys.os" />
+<xsl:param name="sys.os.platform" />
+<xsl:param name="sys.os.version" />
+<xsl:param name="sys.clr.version" />
+
+<msxsl:script language="C#" implements-prefix="nunit2report">
+
+ public string TestCaseName(string path) {
+
+ string[] a = path.Split('.');
+
+ return(a[a.Length-1]);
+ }
+
+</msxsl:script>
+
+<!--
+ TO DO
+ Corriger les alignement sur error
+ Couleur http://nanning.sourceforge.net/junit-report.html
+-->
+
+
+<!--
+ format a number in to display its value in percent
+ @param value the number to format
+-->
+<xsl:template name="display-time">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.000')"/>
+</xsl:template>
+
+<!--
+ format a number in to display its value in percent
+ @param value the number to format
+-->
+<xsl:template name="display-percent">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.00 %')"/>
+</xsl:template>
+
+<!--
+ transform string like a.b.c to ../../../
+ @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+ <xsl:param name="path"/>
+ <xsl:if test="contains($path,'.')">
+ <xsl:text>../</xsl:text>
+ <xsl:call-template name="path">
+ <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="not(contains($path,'.')) and not($path = '')">
+ <xsl:text>../</xsl:text>
+ </xsl:if>
+</xsl:template>
+
+<!--
+ template that will convert a carriage return into a br tag
+ @param word the text from which to convert CR to BR tag
+-->
+<xsl:template name="br-replace">
+ <xsl:param name="word"/>
+ <xsl:choose>
+ <xsl:when test="contains($word,'
')">
+ <xsl:value-of select="substring-before($word,'
')"/>
+ <br/>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="substring-after($word,'
')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$word"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!--
+ =====================================================================
+ classes summary header
+ =====================================================================
+-->
+<xsl:template name="header">
+ <xsl:param name="path"/>
+ <h1><span id=":i18n:UnitTestsResults">Unit Tests Results</span> - <xsl:value-of select="$nant.project.name"/></h1>
+ <table width="100%">
+ <tr>
+ <td align="left">
+ <span id=":i18n:GeneratedBy">Generated by</span> <a target="_blank" href="http://sourceforge.net/projects/nunit2report/">NUnit2Report</a> : <xsl:value-of select="@date"/> - <xsl:value-of select="concat(@time,' ')"/> <a href="#envinfo" id=":i18n:EnvironmentInformation">Environment Information</a>
+ </td>
+ <td align="right"><span id=":i18n:Designed">Designed for use with</span> <a href='http://nunit.sourceforge.net/'>NUnit</a> <span id=":i18n:and">and</span> <a href='http://nant.sourceforge.net/'>NAnt</a>.
+ </td>
+ </tr>
+ </table>
+ <hr size="1"/>
+</xsl:template>
+
+<xsl:template name="summaryHeader">
+ <tr valign="top" class="TableHeader">
+ <td width="50px"><b id=":i18n:Tests">Tests</b></td>
+ <td width="70px"><b id=":i18n:Failures">Failures</b></td>
+ <td width="70px"><b id=":i18n:Errors">Errors</b></td>
+ <td colspan="2"><b id=":i18n:SuccessRate">Success Rate</b></td>
+ <td width="70px" nowrap="nowrap"><b id=":i18n:Time">Time(s)</b></td>
+ </tr>
+</xsl:template>
+
+<!--
+ =====================================================================
+ package summary header
+ =====================================================================
+-->
+<xsl:template name="packageSummaryHeader">
+ <tr class="TableHeader" valign="top">
+ <td width="75%" colspan="3"><b id=":i18n:Name">Name</b></td>
+ <td width="5%"><b id=":i18n:Tests">Tests</b></td>
+ <td width="5%"><b id=":i18n:Errors">Errors</b></td>
+ <td width="5%"><b id=":i18n:Failures">Failures</b></td>
+ <td width="10%" nowrap="nowrap"><b id=":i18n:Time">Time(s)</b></td>
+ </tr>
+</xsl:template>
+
+
+<!--
+ =====================================================================
+ classes summary header
+ =====================================================================
+-->
+<xsl:template name="classesSummaryHeader">
+ <tr class="TableHeader" valign="top">
+ <td width="85%" colspan="2"><b id=":i18n:Name">Name</b></td>
+ <td width="10%"><b id=":i18n:Status">Status</b></td>
+ <td width="5%" nowrap="nowrap"><b id=":i18n:Time">Time(s)</b></td>
+ </tr>
+</xsl:template>
+
+<!--
+ =====================================================================
+ Write the summary report
+ It creates a table with computed values from the document:
+ User | Date | Environment | Tests | Failures | Errors | Rate | Time
+ Note : this template must call at the testsuites level
+ =====================================================================
+-->
+ <xsl:template name="summary">
+ <h2 id=":i18n:Summary">Summary</h2>
+ <xsl:variable name="runCount" select="@total"/>
+ <xsl:variable name="failureCount" select="@failures"/>
+ <xsl:variable name="ignoreCount" select="@not-run"/>
+ <xsl:variable name="total" select="$runCount + $ignoreCount + $failureCount"/>
+
+ <xsl:variable name="timeCount" select="translate(test-suite/@time,',','.')"/>
+
+ <xsl:variable name="successRate" select="$runCount div $total"/>
+ <table border="0" cellpadding="2" cellspacing="0" width="95%" style="border: #dcdcdc 1px solid;">
+ <xsl:call-template name="summaryHeader"/>
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$failureCount > 0">Failure</xsl:when>
+ <xsl:when test="$ignoreCount > 0">Error</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><xsl:value-of select="$runCount"/></td>
+ <td><xsl:value-of select="$failureCount"/></td>
+ <td><xsl:value-of select="$ignoreCount"/></td>
+ <td nowrap="nowrap" width="70px">
+ <xsl:call-template name="display-percent">
+ <xsl:with-param name="value" select="$successRate"/>
+ </xsl:call-template>
+ </td>
+ <td>
+ <xsl:if test="round($runCount * 200 div $total )!=0">
+ <span class="covered">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($runCount * 200 div $total )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ <xsl:if test="round($ignoreCount * 200 div $total )!=0">
+ <span class="ignored">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($ignoreCount * 200 div $total )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ <xsl:if test="round($failureCount * 200 div $total )!=0">
+ <span class="uncovered">
+ <xsl:attribute name="style">width:<xsl:value-of select="round($failureCount * 200 div $total )"/>px</xsl:attribute>
+ </span>
+ </xsl:if>
+ </td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ <span id=":i18n:Note">Note</span>: <i id=":i18n:failures">failures</i> <span id=":i18n:anticipated">are anticipated and checked for with assertions while</span> <i id=":i18n:errors">errors</i> <span id=":i18n:unanticipated">are unanticipated.</span>
+ </xsl:template>
+
+<!--
+ =====================================================================
+ testcase report
+ =====================================================================
+-->
+<xsl:template match="test-case">
+ <xsl:param name="summary.xml"/>
+ <xsl:param name="open.description"/>
+
+ <xsl:variable name="summaries" select="document($summary.xml)" />
+
+ <xsl:variable name="Mname" select="concat('M:',./@name)" />
+
+ <xsl:variable name="result">
+ <xsl:choose>
+ <xsl:when test="./failure"><span id=":i18n:Failure">Failure</span></xsl:when>
+ <xsl:when test="./error"><span id=":i18n:Error">Error</span></xsl:when>
+ <xsl:when test="@executed='False'"><span id=":i18n:Ignored">Ignored</span></xsl:when>
+ <xsl:otherwise><span id=":i18n:Pass">Pass</span></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="newid" select="generate-id(@name)" />
+ <tr valign="top">
+ <xsl:attribute name="class"><xsl:value-of select="$result"/></xsl:attribute>
+
+ <td width="20%" >
+ <xsl:choose>
+ <xsl:when test="$summary.xml != ''">
+ <!-- Triangle image -->
+ <a title="Show/Hide XML Comment" class="summarie"><xsl:attribute name="href">javascript:Toggle('<xsl:value-of select="concat('M:',$newid)"/>');ToggleImage('<xsl:value-of select="concat('I:',$newid)"/>')</xsl:attribute><xsl:attribute name="id"><xsl:value-of select="concat('I:',$newid)"/></xsl:attribute>
+ <!-- Set the good triangle image 6/4 font-family:Webdings-->
+ <xsl:choose>
+ <xsl:when test="$result != "Pass"">-</xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$open.description='yes'">-</xsl:when>
+ <xsl:otherwise>+</xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </a>
+ </xsl:when>
+ </xsl:choose>
+ <!-- If failure, add click on the test method name and color red -->
+ <xsl:choose>
+ <xsl:when test="$result = 'Failure' or $result = 'Error'"> <a title="Show/Hide message error">
+ <xsl:attribute name="href">javascript:Toggle('<xsl:value-of select="$newid"/>')</xsl:attribute>
+ <xsl:attribute name="class">error</xsl:attribute>
+ <xsl:value-of select="nunit2report:TestCaseName(./@name)"/>
+ </a>
+ </xsl:when>
+ <xsl:when test="$result = 'Ignored'"> <a title="Show/Hide message error">
+ <xsl:attribute name="href">javascript:Toggle('<xsl:value-of select="$newid"/>')</xsl:attribute>
+ <xsl:attribute name="class">ignored</xsl:attribute>
+ <xsl:value-of select="nunit2report:TestCaseName(./@name)"/>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="class">method</xsl:attribute> <xsl:value-of select="nunit2report:TestCaseName(./@name)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td width="65%" style="padding-left:3px" height="9px">
+ <xsl:choose>
+ <xsl:when test="$result = 'Pass'">
+ <span class="covered" style="width:200px"></span>
+ </xsl:when>
+ <xsl:when test="$result = 'Ignored'">
+ <span class="ignored" style="width:200px"></span>
+ </xsl:when>
+ <xsl:when test="$result = 'Failure' or $result = 'Error'">
+ <span class="uncovered" style="width:200px"></span>
+ </xsl:when>
+ </xsl:choose>
+ <!-- The test method description-->
+ <xsl:choose>
+ <xsl:when test="$summary.xml != ''">
+ <div class="description" style="display:block">
+ <!-- Attribute id -->
+ <xsl:attribute name="id"><xsl:value-of select="concat('M:',$newid)"/></xsl:attribute>
+ <!-- Open method description if failure -->
+ <xsl:choose>
+ <xsl:when test="$result != "Pass"">
+ <xsl:attribute name="style">display:block</xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$open.description = 'yes'">
+ <xsl:attribute name="style">display:block</xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="style">display:none</xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ <!-- The description of the test method -->
+ <xsl:value-of select="normalize-space($summaries//member[@name=$Mname]/summary/text())"/>
+ </div>
+ </xsl:when>
+ </xsl:choose>
+ </td>
+ <td><xsl:attribute name="id">:i18n:<xsl:value-of select="$result"/></xsl:attribute><xsl:value-of select="$result"/></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="@time"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+
+ <xsl:if test="$result != "Pass"">
+ <tr style="display: block;">
+ <xsl:attribute name="id">
+ <xsl:value-of select="$newid"/>
+ </xsl:attribute>
+ <td colspan="4" class="FailureDetail">
+ <xsl:apply-templates select="./failure"/>
+ <xsl:apply-templates select="./error"/>
+ <xsl:apply-templates select="./reason"/>
+ </td>
+ </tr>
+ </xsl:if>
+</xsl:template>
+
+<!-- Note : the below template error and failure are the same style
+ so just call the same style store in the toolkit template -->
+<!-- <xsl:template match="failure">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="error">
+ <xsl:call-template name="display-failures"/>
+</xsl:template> -->
+
+<!-- Style for the error and failure in the tescase template -->
+<!-- <xsl:template name="display-failures">
+ <xsl:choose>
+ <xsl:when test="not(@message)">N/A</xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@message"/>
+ </xsl:otherwise>
+ </xsl:choose> -->
+ <!-- display the stacktrace -->
+<!-- <code>
+ <p/>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="."/>
+ </xsl:call-template>
+ </code> -->
+ <!-- the later is better but might be problematic for non-21" monitors... -->
+ <!--pre><xsl:value-of select="."/></pre-->
+<!-- </xsl:template>
+ -->
+
+<!--
+ =====================================================================
+ Environtment Info Report
+ =====================================================================
+-->
+<xsl:template name="envinfo">
+ <a name="envinfo"></a>
+ <h2 id=":i18n:EnvironmentInformation">Environment Information</h2>
+ <table border="0" cellpadding="5" cellspacing="2" width="95%">
+ <tr class="TableHeader">
+ <td id=":i18n:Property">Property</td>
+ <td id=":i18n:Value">Value</td>
+ </tr>
+ <tr>
+ <td id=":i18n:NAntLocation">NAnt Location</td>
+ <td><xsl:value-of select="$nant.filename"/></td>
+ </tr>
+ <tr>
+ <td id=":i18n:NAntVersion">NAnt Version</td>
+ <td><xsl:value-of select="$nant.version"/></td>
+ </tr>
+ <tr>
+ <td id=":i18n:Buildfile">Buildfile</td>
+ <td><xsl:value-of select="$nant.project.buildfile"/></td>
+ </tr>
+ <tr>
+ <td id=":i18n:BaseDirectory">Base Directory</td>
+ <td><xsl:value-of select="$nant.project.basedir"/></td>
+ </tr>
+ <tr>
+ <td id=":i18n:OperatingSystem">Operating System</td>
+ <td><xsl:value-of select="$sys.os"/></td>
+ </tr>
+ <tr>
+ <td id=":i18n:NETCLRVersion">.NET CLR Version</td>
+ <td><xsl:value-of select="$sys.clr.version"/></td>
+ </tr>
+ </table>
+ <a href="#top" id=":i18n:Backtotop">Back to top</a>
+</xsl:template>
+
+<!-- I am sure that all nodes are called -->
+<xsl:template match="*">
+ <xsl:apply-templates/>
+</xsl:template>
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tools/sourceforge_scripts/fix_group_perm.sh b/tools/sourceforge_scripts/fix_group_perm.sh
new file mode 100644
index 0000000..94f5d3a
--- /dev/null
+++ b/tools/sourceforge_scripts/fix_group_perm.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+BASEDIR=/home/groups/n/nl/nlog
+find $BASEDIR/htdocs -type d | grep -v "htdocs$" | xargs -izzz chmod 2775 zzz
+find $BASEDIR/htdocs -type f | xargs chmod 0664
diff --git a/tools/sourceforge_scripts/unpack_help.sh b/tools/sourceforge_scripts/unpack_help.sh
new file mode 100644
index 0000000..180e45e
--- /dev/null
+++ b/tools/sourceforge_scripts/unpack_help.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+BASEDIR=/home/groups/n/nl/nlog
+rm -rf $BASEDIR/htdocs/help
+mkdir $BASEDIR/htdocs/help
+cd $BASEDIR/htdocs/help && unzip -o $BASEDIR/help.zip
+find $BASEDIR/htdocs/help -type d | xargs -izzz chmod 2775 zzz
+find $BASEDIR/htdocs/help -type f | xargs chmod 0664
diff --git a/tools/sourceforge_scripts/unpack_website.sh b/tools/sourceforge_scripts/unpack_website.sh
new file mode 100644
index 0000000..ec5ad72
--- /dev/null
+++ b/tools/sourceforge_scripts/unpack_website.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+BASEDIR=/home/groups/n/nl/nlog
+cd $BASEDIR/htdocs && unzip -o $BASEDIR/website.zip
+find $BASEDIR/htdocs -type d | grep -v "htdocs$" | xargs -izzz chmod 2775 zzz
+find $BASEDIR/htdocs -type f | xargs chmod 0664
diff --git a/tools/web_install.sh b/tools/web_install.sh
new file mode 100644
index 0000000..f977251
--- /dev/null
+++ b/tools/web_install.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+HTML_DIR=$1
+
+umask 002
+echo Installing web.zip...
+unzip -o -d $HTML_DIR web.zip
diff --git a/update_version.bat b/update_version.bat
new file mode 100644
index 0000000..c1a04db
--- /dev/null
+++ b/update_version.bat
@@ -0,0 +1,11 @@
+ at echo off
+rem
+rem This script updates AssemblyBuildInfo.cs in source code directories based on
+rem the contents of NLog.version file.
+rem
+rem When using Visual C# 2003, 2005 or NAnt this is done automatically, you only
+rem need to do this by hand when compiling .NET Compact Framework project.
+rem
+tools\UpdateBuildNumber.exe NLog.version src/NLog/AssemblyBuildInfo.cs build/NLog.buildversion
+tools\UpdateBuildNumber.exe NLog.version src/NLog.ComInterop/AssemblyBuildInfo.cs build/NLog.buildversion
+
diff --git a/web/NLog.jpg b/web/NLog.jpg
new file mode 100644
index 0000000..aca39d9
Binary files /dev/null and b/web/NLog.jpg differ
diff --git a/web/api.xml b/web/api.xml
new file mode 100644
index 0000000..f9dd8c5
--- /dev/null
+++ b/web/api.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" subid="api">
+ <h1>NLog API</h1>
+ <p>
+ NLog provides the following Application Programming Interfaces (APIs)
+ </p>
+ <ul>
+ <li><link href="netapi">.NET API</link> - native API</li>
+ <li><link href="capi">C/C++ API</link> - a wrapper API to be used in legacy COM applications</li>
+ <li><link href="comapi">COM API</link> - a wrapper API to be used in legacy C/C++ applications</li>
+ </ul>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:25:00 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
+
diff --git a/web/blog.xml b/web/blog.xml
new file mode 100644
index 0000000..79238d2
--- /dev/null
+++ b/web/blog.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="blog">
+ <h1>Blog</h1>
+ <p>For my blog where I'll be talking about NLog and <a href="http://www.sooda.org/">Sooda</a> click <a href="http://blog.jkowalski.net/">here</a>.</p>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/bug.xml b/web/bug.xml
new file mode 100644
index 0000000..d18ec3e
--- /dev/null
+++ b/web/bug.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="support" subid="bug">
+ <h1>Report NLog Bug</h1>
+ <p>NLog uses TRAC for bug tracking and project management. The interface can be found <a href="http://trac.sav.net/nlog">here.</a></p>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/capi.xml b/web/capi.xml
new file mode 100644
index 0000000..c008aac
--- /dev/null
+++ b/web/capi.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" subid="capi">
+ <h1>C/C++ API</h1>
+ <p>
+ NLog supports a C/C++ logging API that can be used in scenarios that require the use
+ of C/C++ components in .NET projects. Typical case is porting a legacy systen to .NET
+ where some parts are rewritten in managed code while some remain unmanaged.
+ </p>
+ <p>
+ This API is available through <code>NLogC.dll</code> which is a mixed-mode (managed/unmanaged)
+ assembly. It provides the following set exported functions:
+ </p>
+
+ <code lang="C#" src="examples/web/NLogC.cpp" />
+
+ <p>
+ For your convenience, the following defines which use a <code>TCHAR</code> data type are available:
+ </p>
+
+ <code lang="C#" src="examples/web/NLogCdef.cpp" />
+
+ <p>
+ Here's the short summary of what these functions do (modulo their ANSI/UNICODE variants):
+ </p>
+
+ <ul>
+ <li><code>NLog_ConfigureFromFile(filename)</code></li>
+ <p>
+ Configures NLog from the specified config file. You should call this function at the beginning of your
+ program if you want to specify your own config file. If you don't do this, NLog will attempt to find
+ the config file the first time you use any of the logging functions using the logic described <link href="config">here</link>.
+ </p>
+ <li><code>NLog_Log(level,logger,logMessage,...)</code></li>
+ <p>
+ Writes the specified <code>logMessage</code> at the specified <code>level</code> to the specified <code>logger</code>.
+ <code>level</code> is a NLogLevel enumeration value an can be one of the following constants:
+ <code>logMessage</code> is a message to be written. It may include <code>printf()</code>-style parameters.
+ </p>
+ <ul>
+ <li>NLOG_DEBUG</li>
+ <li>NLOG_INFO</li>
+ <li>NLOG_WARN</li>
+ <li>NLOG_ERROR</li>
+ <li>NLOG_FATAL</li>
+ </ul>
+ <p/>
+ <li><code>NLog_LogV(level,logger,logMessage,parameters)</code></li>
+ <p>
+ Same as <code>NLog_Log()</code> but lets you pass message parameters as <code>va_list</code> (useful for wrapping
+ in your own logging layer).
+ </p>
+ <li><code>NLog_Debug(logger,logMessage,...)</code></li>
+ <p>
+ Equivalent to calling <code>NLog_Log(NLOG_DEBUG,logger,logMessage,...)</code>
+ </p>
+ <li><code>NLog_Info(logger,logMessage,...)</code></li>
+ <p>
+ Equivalent to calling <code>NLog_Log(NLOG_INFO,logger,logMessage,...)</code>
+ </p>
+ <li><code>NLog_Warn(logger,logMessage,...)</code></li>
+ <p>
+ Equivalent to calling <code>NLog_Log(NLOG_WARN,logger,logMessage,...)</code>
+ </p>
+ <li><code>NLog_Error(logger,logMessage,...)</code></li>
+ <p>
+ Equivalent to calling <code>NLog_Log(NLOG_ERROR,logger,logMessage,...)</code>
+ </p>
+ <li><code>NLog_Fatal(logger,logMessage,...)</code></li>
+ <p>
+ Equivalent to calling <code>NLog_Log(NLOG_FATAL,logger,logMessage,...)</code>
+ </p>
+ </ul>
+ <p>
+ The C/C++ API as-is is meant primarily to be wrapped by your own high-level logging API (every programmer has one, hasn't he?).
+ An example of such an API implemented as C++ class is provided in <code>src/NLogC/NLogger.h</code>.
+ </p>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
+
diff --git a/web/checkbox0.gif b/web/checkbox0.gif
new file mode 100644
index 0000000..bb00f16
Binary files /dev/null and b/web/checkbox0.gif differ
diff --git a/web/checkbox1.gif b/web/checkbox1.gif
new file mode 100644
index 0000000..1a39e6f
Binary files /dev/null and b/web/checkbox1.gif differ
diff --git a/web/comapi.xml b/web/comapi.xml
new file mode 100644
index 0000000..5c82466
--- /dev/null
+++ b/web/comapi.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" subid="comapi">
+ <h1>COM API</h1>
+ <p>
+ NLog features a COM Interop API tha can be used to provide logging for legacy COM applications/components that
+ are deployed as part of a .NET solution. COM support is available with 2 coclasses with ProgIDs: <code>NLog.LogManager</code>
+ which lets you perform basic configuration and <code>NLog.Logger</code> which does the actual logging.
+ </p>
+ <p>
+ COM components are supported for many languages, both scripting and compiled. Basic usage is
+ similar to the .NET API, with the following exceptions:
+ </p>
+ <ul>
+ <li>Instances of loggers are created directly, you don't need to use LogManager to get them.</li>
+ <li>Because COM classes don't support passing parameters at construction time, you need to set
+ each logger's name by setting its <code>LoggerName</code></li>
+ <li>Passing of format arguments isn't supported</li>
+ <li>Logger levels (arguments to the <code>Log()</code> method) are passed as strings instead of enumeration values - this provides maximum compatibility
+ with scripting environments.</li>
+ </ul>
+ <p>
+ The following example demonstrates the use of NLog COM api for JScript.
+ </p>
+
+ <code lang="JScript" src="examples/web/test.js" />
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
+
diff --git a/web/conditions.xsl b/web/conditions.xsl
new file mode 100644
index 0000000..65fd650
--- /dev/null
+++ b/web/conditions.xsl
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:include href="style.xsl" />
+
+ <xsl:template match="*" mode="content">
+ <h1>Conditions</h1>
+ <p>
+ Conditions are used in various places to filter log events based on their content.
+ </p>
+
+ <h3>Condition language</h3>
+ <p>
+ NLog supports a simple language to express conditions. The language consists of:
+ </p>
+ <ul>
+ <li>relational operators (<b>==</b>, <b>!=</b>, <b><=</b>, <b><=</b>, <b>>=</b> and <b>></b>)</li>
+ <li><b>and</b>, <b>or</b>, <b>not</b> boolean operators</li>
+ <li>string literals which are always evaluated as <a href="layoutrenderers.html">layouts</a> - <b>'${somerenderer}'</b></li>
+ <li>boolean literals - <b>true</b> and <b>false</b></li>
+ <li>log level literals - <b>LogLevel.Trace</b>, <b>LogLevel.Debug</b>, ... <b>LogLevel.Fatal</b></li>
+ <li>numeric literals - <b>12345</b> (integer literal) and <b>12345.678</b> (floating point literal)</li>
+ <li>predefined keywords to access the most common log event properties - <b>level</b>, <b>message</b> and <b>logger</b></li>
+ <li>braces - to override default priorities and group expressions together</li>
+ </ul>
+ <h3>Examples</h3>
+ <p>
+ Here are some examples of conditions:
+ </p>
+ <ul>
+ <li><b>level > LogLevel.Debug</b> - matches the messages whose level is greater than Debug</li>
+ <li><b>(level > LogLevel.Debug) or contains(message,'xxx')</b> - matches the messages whose level is greater than Debug or which include the xxx substring in the log message</li>
+ <li><b>starts-with(logger,'Kopytko.')</b> - matches the loggers whose names start with <code>Kopytko.</code></li>
+ <li><b>ends-with(logger,'.SQL') or ends-with(logger,'.XML')</b> - matches the loggers whose names end with either <code>.SQL</code> or <code>.XML</code></li>
+ <li><b>true</b> - matches everything</li>
+ <li><b>false</b> - matches nothing</li>
+ <li><b>length(message) > 100</b> - matches the log events where the length of the log message is greater than 100</li>
+ <li><b>'${shortdate}' == '2005-11-10'</b> - matches on the specified date</li>
+ </ul>
+ <h3>Available functions</h3>
+ <p>
+ The following functions are available:
+ </p>
+ <div class="noborder" style="width: 600px">
+ <table class="listtable">
+ <tr>
+ <th>Name</th>
+ <th>Description</th>
+ <th><nobr>Defined in</nobr></th>
+ </tr>
+ <xsl:apply-templates select="//method[attribute/@name='NLog.ConditionMethodAttribute']" mode="list">
+ <xsl:sort select="attribute[@name='NLog.ConditionMethodAttribute']/property[@name='Name']/@value" />
+ </xsl:apply-templates>
+ </table>
+ </div>
+ </xsl:template>
+
+ <xsl:template match="method" mode="list">
+ <xsl:variable name="method_tag" select="attribute[@name='NLog.ConditionMethodAttribute']/property[@name='Name']/@value" />
+ <tr>
+ <td class="name"><xsl:value-of select="$method_tag" />(<xsl:for-each select="parameter"><xsl:if test="position() != 1">,</xsl:if><xsl:value-of select="@name" /></xsl:for-each>)</td>
+ <td class="description"><xsl:apply-templates select="documentation/summary" />
+ Returns: <xsl:apply-templates select="documentation/returns" /></td>
+ <td class="assembly"><xsl:value-of select="../../../@name" /></td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="@* | node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@* | node()" />
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="summary">
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="property[@set='false']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@name='Name']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@name='Type']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@type='NLog.Layout']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@type='NLog.ILayout']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="c">
+ <code><xsl:apply-templates /></code>
+ </xsl:template>
+
+ <xsl:template match="code">
+ <code><pre class="example"><xsl:apply-templates /></pre></code>
+ </xsl:template>
+
+ <xsl:template match="see">
+ <code><xsl:value-of select="@cref" /></code>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/web/config.xml b/web/config.xml
new file mode 100644
index 0000000..35fd1fa
--- /dev/null
+++ b/web/config.xml
@@ -0,0 +1,546 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" subid="config">
+ <h1>NLog Configuration Options</h1>
+ <p>NLog can be configured in many ways, both <a href="#api">programmatically</a> and using config <a href="#file">files</a>.
+ This document describes the available configuration options.</p>
+ <a name="file" />
+ <h2>Logging configuration</h2>
+ <p>
+ NLog attempts
+ to automatically configure itself on startup, by looking for the configuration files in some standard places.
+ The following locations will be searched when executing a stand-alone *.exe application:
+ </p>
+ <ul>
+ <li>
+ standard application configuration file (usually <font face="Courier New">applicationname.exe.config)</font>
+ </li>
+ <li>
+ <font face="Courier New">applicationname.exe.nlog</font> in application's directory
+ </li>
+ <li>
+ <font face="Courier New">NLog.config</font> in application's directory
+ </li>
+ <li>
+ <font face="Courier New">NLog.dll.nlog</font> in a directory where <font face="Courier New">NLog.dll</font> is located
+ </li>
+ <li>
+ file name pointed by the <font face="Courier New">NLOG_GLOBAL_CONFIG_FILE</font> environment variable (if defined)
+ </li>
+ </ul>
+ <p>
+ In case of an ASP.NET application, the following files are searched:
+ </p>
+ <ul>
+ <li>
+ standard web application file <font face="Courier New">web.config</font>
+ </li>
+ <li>
+ <font face="Courier New">web.nlog</font> located in the same directory as <font face="Courier New">web.config</font>
+ </li>
+ <li>
+ <font face="Courier New">NLog.config</font> in application's directory
+ </li>
+ <li>
+ <font face="Courier New">NLog.dll.nlog</font> in a directory where <font face="Courier New">NLog.dll</font> is located
+ </li>
+ <li>
+ file name pointed by the <font face="Courier New">NLOG_GLOBAL_CONFIG_FILE</font> environment variable (if defined)
+ </li>
+ </ul>
+ <p>
+ The .NET Compact Framework doesn't recognize application configuration files (*.exe.config)
+ nor environmental variables, so NLog only looks in these locations:
+ </p>
+ <ul>
+ <li>
+ <font face="Courier New">applicationname.exe.nlog</font> in application's directory
+ </li>
+ <li>
+ <font face="Courier New">NLog.config</font> in application's directory
+ </li>
+ <li>
+ <font face="Courier New">NLog.dll.nlog</font> in a directory where <font face="Courier New">NLog.dll</font> is located
+ </li>
+ </ul>
+ <h4>Configuration file format</h4>
+ <p>
+ NLog supports two configuration file formats:
+ </p>
+ <ul>
+ <li>configuration embedded within the standard *.exe.config or web.config file</li>
+ <li>simplified configuration, stored in a separate file</li>
+ </ul>
+ <p>
+ In the first variant, we use a standard configSections mechanism, which makes our file look like this:
+ </p>
+ <code lang="XML">
+ <![CDATA[<?xml version="1.0" encoding="utf-8" ?>
+ <configuration>
+ <configSections>
+ <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
+ </configSections>
+ <nlog>
+ </nlog>
+ </configuration>
+ ]]>
+ </code>
+ <p>
+ The simplified format is the pure XML having the <x>
+ <nlog />
+ </x> element as its root.
+ The use of namespaces is optional, but it enables the Intellisense in Visual Studio.
+ </p>
+ <code lang="XML">
+ <![CDATA[<?xml version="1.0" encoding="utf-8" ?>
+ <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ </nlog>
+ ]]>
+ </code>
+ <p>
+ Note that NLog config file is case-insensitive when not using namespaces
+ and is case-sensitive when you use them. Intellisense only works with case-sensitive
+ configurations.
+ </p>
+ <h4>Configuration elements</h4>
+ <p>
+ You can use the following elements as children to <x>
+ <nlog />
+ </x>. The first two elements from the list are required to be present in all
+ NLog configuration files, the remaining ones are optional and can be useful in
+ advanced scenarios.
+ </p>
+ <ul>
+ <li>
+ <x><targets /></x> - defines log targets/outputs
+ </li>
+ <li>
+ <x><rules /></x> - defines log routing rules
+ </li>
+ <li>
+ <x><extensions /></x> - loads NLog extensions from the *.dll file
+ </li>
+ <li>
+ <x><include /></x> - includes external configuration file
+ </li>
+ <li>
+ <x><variable /></x> - sets the value of a configuration variable
+ </li>
+ </ul>
+ <h4>Targets</h4>
+ <p>
+ The <x><targets /></x> section defines log targets/outputs. Each target is represented by a <x><target /></x> element.
+ There are two attributes required for each target:
+ </p>
+ <ul>
+ <li>
+ <b>name</b> - target name
+ </li>
+ <li>
+ <b>type</b> - target type - such as "File", "Database", "Mail". When using namespaces this attribute is named <b>xsi:type</b>.
+ </li>
+ </ul>
+ <p>
+ In addition to these attributes, targets usually accept other parameters, which influence the way diagnostic
+ traces are written. Each target has a different set of parameters, they are described in detail
+ on project's homepage and they are context-sensitive. Intellisense is also available in Visual Studio.
+ </p>
+ <p>
+ For example - the "<b>File</b>" target accepts the <b>fileName</b> parameter which defines
+ output file name and the <b>Console</b> target has the <b>error</b> parameter which determines
+ whether the diagnostic traces are written to standard error (stderr) instead of standard output
+ (stdout) of the process.
+ </p>
+ <p>
+ This example demonstrates a <x><targets /></x> section which defines multiple targets: two files, one network target and
+ OutputDebugString target:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <targets>
+ <target name="f1" xsi:type="File" fileName="file1.txt" />
+ <target name="f2" xsi:type="File" fileName="file2.txt" />
+ <target name="n1" xsi:type="Network" address="tcp://localhost:4001" />
+ <target name="ds" xsi:type="OutputDebugString" />
+ </targets>
+ ]]>
+ </code>
+ <p>
+ NLog provides many predefined targets. They are described on the project's homepage.
+ It's actually very easy to create your own target - it requires about 15-20 lines of
+ code and is described in the
+ <a href="http://www.nlog-project.org/documentation.html">documentation</a>.
+ </p>
+ <h4>Rules</h4>
+ <p>
+ Log routing rules are defined in the <x>
+ <rules />
+ </x> section. It is a simple routing table, where we define the list of targets
+ that should be written to for each combination of source/logger name and log level.
+ Rules are processed starting with the first rule in the list. When a
+ rule matches, log messages are directed to target(s) in that rule. If a
+ rule is marked as final, rules beneath the current rule are not
+ processed.
+ </p>
+ <p>
+ Each routing table entry is a <x>
+ <logger />
+ </x> element, which accepts the following attributes:
+ </p>
+ <ul>
+ <li>
+ <font face="Courier New">name</font> - source/logger name (may include wildcard characters <b>*</b>)
+ </li>
+ <li>
+ <font face="Courier New">minlevel</font> - minimal log level for this rule to match
+ </li>
+ <li>
+ <font face="Courier New">maxlevel</font> - maximum log level for this rule to match
+ </li>
+ <li>
+ <font face="Courier New">level</font> - single log level for this rule to match
+ </li>
+ <li>
+ <font face="Courier New">levels </font>- comma separated list of log levels for this rule to match
+ </li>
+ <li>
+ <font face="Courier New">writeTo</font> - comma separated list of target that should be written to when this rule matches.
+ </li>
+ <li>
+ <font face="Courier New">final</font> - make this rule final. No further rules are processed when any
+ final rule matches.
+ </li>
+ </ul>
+ <p>
+ Some examples:
+ </p>
+ <ul>
+ <li>
+ <x>
+ <logger name="Name.Space.Class1" minlevel="Debug" writeTo="f1" />
+ </x> - all messages from the <font face="Courier New">Class1</font> in the <font face="Courier New">Name.Space</font> whose level is <font face="Courier New">Debug</font> or higher are written to the "<font face="Courier New">f1</font>" target.
+ </li>
+ <li>
+ <x>
+ <logger name="Name.Space.Class1" levels="Debug,Error" writeTo="f1" />
+ </x> - all messages from the <font face="Courier New">Class1</font> in the <font face="Courier New">Name.Space</font> whose level is either <font face="Courier New">Debug</font> or <font face="Courier New">Error</font> or higher are written to the "<font face="Courier New">f1</font>" target.
+ </li>
+ <li>
+ <x>
+ <logger name="Name.Space.*" writeTo="f3,f4" />
+ </x>
+ - messages from any class in the <font face="Courier New">Name.Space</font> namespace are written to both "<font face="Courier New">f3</font>" and "<font face="Courier New">f4</font>" targets regardless of their levels.
+ </li>
+ <li>
+ <x>
+ <logger name="Name.Space.*" minlevel="Debug" maxlevel="Error" final="true" />
+ </x>
+ - messages from any class in the <font face="Courier New">Name.Space</font> namespace whose level is
+ between <font face="Courier New">Debug</font> and <font face="Courier New">Error</font> (which makes it
+ <font face="Courier New">Debug,Info,Warn,Error</font>) are rejected (as there's no
+ <font face="Courier New">writeTo</font> clause)
+ and no futher rules are processed for them (because of the <font face="Courier New">final="true"</font> setting)
+ </li>
+ </ul>
+ <p>
+ In the simplest cases the entire logging configuration consists of a single <x><target/></x> and
+ a single <x><logger /></x> rule that routes messages to this target depending on their level.
+ As the application grows, adding more targets and rules is very simple.
+ </p>
+ <h4>Contextual information</h4>
+ <p>
+ One of NLog's strongest assets is the ability to use layouts. They include pieces of text surrounded by a pair
+ of "<b>${</b>" (dollar sign + left curly brace) and "<b>}</b>" (right curly brace). The markup denotes
+ "layout renderers" which can be used to insert pieces of <b>contextual information</b> into the text.
+ Layouts can be used in many places, for example they can control the format of information written on the
+ screen or sent to a file, but also to control the file names themselves. This is very powerful,
+ which we'll see in a moment.
+ </p>
+ <p>
+ Let's assume, that we want to augment each message written to the console with:
+ </p>
+ <ul>
+ <li>current date and time</li>
+ <li>name of the class and method that emitted the log message</li>
+ <li>log level</li>
+ <li>message text</li>
+ </ul>
+ <p>This is very easy:</p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="c" xsi:type="Console" layout="${longdate} ${callsite} ${level} ${message}" />
+ ]]>
+ </code>
+ <p>
+ We can make each messages for each logger go to a separate file, as in the following example:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="f" xsi:type="File" fileName="${logger}.txt" />
+ ]]>
+ </code>
+
+ <p>
+ Ay you can see the <font face="Courier New">${logger}</font> layout renderer was used
+ in the <font face="Courier New">fileName</font> attribute, which causes each log message
+ to be written to the file whose name includes the logger name. The above example will
+ create the following files:
+ </p>
+ <ul>
+ <li>Name.Space.Class1.txt</li>
+ <li>Name.Space.Class2.txt</li>
+ <li>Name.Space.Class3.txt</li>
+ <li>Other.Name.Space.Class1.txt</li>
+ <li>Other.Name.Space.Class2.txt</li>
+ <li>Other.Name.Space.Class3.txt</li>
+ <li>...</li>
+ </ul>>
+ <p>It's a frequent requirement to be able to keep log files for each day separate.
+ This is trivial, too, thanks to the ${shortdate} layout renderer:</p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="f" xsi:type="File" fileName="${shortdate}.txt" />
+ ]]>
+ </code>
+ <p>
+ How about givin each employee their own log file? The ${windows-identity} layout renderer will do the trick:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="f" xsi:type="File" fileName="${windows-identity:domain=false}.txt" />
+ ]]>
+ </code>
+ <p>
+ Thanks to this simple setting NLog will create a set of files named after our employees' logins:
+ </p>
+ <ol>
+ <li>Administrator.txt</li>
+ <li>MaryManager.txt</li>
+ <li>EdwardEmployee.txt</li>
+ <li>...</li>
+ </ol>
+ <p>
+ More complex cases are of course possible. The following sample demonstrates the way of creating
+ a distinct log file for each person per day. Log files for each day are stored in a separate directory:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="f" xsi:type="File" fileName="${shortdate}/${windows-identity:domain=false}.txt" />
+ ]]>
+ </code>
+ <p>This creates the following files:</p>
+ <ol>
+ <li>2006-01-01/Administrator.txt</li>
+ <li>2006-01-01/MaryManager.txt</li>
+ <li>2006-01-01/EdwardEmployee.txt</li>
+ <li>2006-01-02/Administrator.txt</li>
+ <li>2006-01-02/MaryManager.txt</li>
+ <li>2006-01-02/EdwardEmployee.txt</li>
+ <li>...</li>
+ </ol>
+
+ <p>
+ NLog provides many predefined layout renderers. They are described on the
+ <a href="http://www.nlog-project.org/layoutrenderers.html">http://www.nlog-project.org/layoutrenderers.html</a> page.
+ It's very easy to create your own layout renderer. It just takes 15-20 lines of code and is described in the <a href="http://www.nlog-project.org/documentation.html">documentation</a>
+ section of the project website.
+ </p>
+
+ <h4>Include files </h4>
+ <p>
+ It's sometimes desired to split the configuration file into many smaller ones.
+ NLog provides an include file mechanism for that. To include an external file, you simply use
+ It's worth noting that the fileName attribute, just like most attributes in
+ NLog config file(s), may include dynamic values using the familiar
+ ${var} notation, so it's possible to include different files based on environmental properties.
+ The following configuration example demonstrates this, by loading file whose name is derived from
+ the name of the machine we're running on.
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <nlog>
+ ...
+ <include file="${basedir}/${machinename}.config" />
+ ...
+ </nlog>
+ ]]>
+ </code>
+ <p>
+ Variables let us write complex or repeatable expression (such as file names) in a concise manner.
+ To define a variable we use the <x><variable name="var" value="xxx" /></x> syntax.
+ Once defined, variables can be used as if they were layout renderers - by using ${var} syntax, as demonstrated in
+ the following example:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <nlog>
+ <variable name="logDirectory" value="${basedir}/logs/${shortdate}" />
+
+ <targets>
+ <target name="file1" xsi:type="File" fileName="${logDirectory}/file1.txt" />
+ <target name="file2" xsi:type="File" fileName="${logDirectory}/file2.txt" />
+ </targets>
+ </nlog>
+ ]]>
+ </code>
+
+ <h4>Automatic reconfiguration</h4>
+ <p>
+ The configuration file is read automatically at program startup. In a long running process (such as a Windows
+ service or an ASP.NET application) it's sometimes desirable to temporarily increase the log level without
+ stopping the application. NLog can monitor logging
+ configuration files and re-read them each time they are modified. To enable this mechanism, you simply set
+ <x><nlog autoReload="true" /></x> in your configuration file. Note that automatic reconfiguration
+ supports include files, so each time one of the files include is changed, the entire configuration gets reloaded.
+ </p>
+
+ <h4>Troubleshooting logging</h4>
+ <p>
+ Sometimes our application doesn't write anything to the log files, even though we have supposedly configured
+ logging properly. There can be many reasons for logs not being written. The most common problem are permissions,
+ usually in an ASP.NET process, where the aspnet_wp.exe or w3wp.exe process may not have write access to the directory
+ where we want to store logs.
+
+ NLog is designed to swallow run-time exceptions that may result from
+ logging. The following settings can change this behavior and/or
+ redirect these messages.
+ </p>
+ <ul>
+ <li>
+ <x>
+ <nlog throwExceptions="true" />
+ </x>- adding throwExceptions attribute in the config file causes NLog not to mask exceptions and pass them
+ to the calling application instead. This attribute is useful at deployment time to quickly locate any problems.
+ It's recommended to turn throwExceptions to "false" as soon as the application is properly configured to run,
+ so that any accidental logging problems won't crash the application.
+ </li>
+ <li>
+ <x>
+ <nlog internalLogFile="file.txt" />
+ </x>- adding internalLogFile cause NLog to write its internal debugging messages to the specified file.
+ This includes any exceptions that may be thrown during logging.
+ </li>
+ <li>
+ <x>
+ <nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" />
+ </x> - determines internal log level. The higher the level, the less verbose the internal log output.
+ </li>
+ <li>
+ <x>
+ <nlog internalLogToConsole="false|true" />
+ </x> - sends internal logging messages to the console.
+ </li>
+ <li>
+ <x>
+ <nlog internalLogToConsoleError="false|true" />
+ </x> - sends internal logging messages to the console error output (stderr).
+ </li>
+ </ul>
+
+ <h4>Asynchronous processing, wrapper and compound targets</h4>
+ <p>
+ NLog provides wrapper and compound targets which modify other targets' behaviour by adding features like:
+ </p>
+ <ul>
+ <li>asynchronous processing (wrapped target runs in a separate thread)</li>
+ <li>retry-on-error</li>
+ <li>load balancing (round-robin targets)</li>
+ <li>buffering</li>
+ <li>filtering</li>
+ <li>backup targets (failover)</li>
+ <li>and others described on <a href="http://www.nlog-project.org/targets.html">http://www.nlog-project.org/targets.html</a></li>
+ </ul>
+ <p>
+ To define a wrapper or compound target in the configuration file,
+ simply nest a target node within another target node. You can even wrap
+ a wrapper target. There are no limits on depth.
+ For example, to add asynchronous logging with retry-on-error functionality
+ add this to your configuration file:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <targets>
+ <target name="n" xsi:type="AsyncWrapper">
+ <target xsi:type="RetryingWrapper">
+ <target xsi:type="File" fileName="${file}.txt" />
+ </target>
+ </target>
+ </targets>
+ ]]>
+ </code>
+ <p>
+ Because asynchronous processing is a common scenario, NLog supports a shorthand notation
+ to enable it for all targets without the need to specify explicit wrappers. You simply
+ set <x><targets async="true" /></x> and all your targets will be wrapped with the AsyncWrapper target.
+ </p>
+
+ <h4>Default wrappers</h4>
+ <p>
+ Sometimes we require ALL targets to be wrapped in the same way, for example to add buffering and/or retrying. NLog provides
+ <x><default-wrapper /></x> syntax for that. You simply put this element in the <x><targets /></x> section and all your targets
+ will be automatically wrapped with the specified wrapper. Note that <x><default-wrapper /></x> applies to the single <x><targets /></x>
+ section only and you can have multiple sections so you can define groups of targets that are wrapped in a similar manner.
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <nlog>
+ <targets>
+ <default-wrapper xsi:type="BufferingWrapper" bufferSize="100" />
+ <target name="f1" xsi:type="File" fileName="f1.txt" />
+ <target name="f2" xsi:type="File" fileName="f2.txt" />
+ </targets>
+
+ <targets>
+ <default-wrapper xsi:type="AsyncWrapper">
+ <wrapper xsi:type="RetryingWrapper" />
+ </default-wrapper>
+
+ <target name="n1" xsi:type="Network" address="tcp://localhost:4001" />
+ <target name="n2" xsi:type="Network" address="tcp://localhost:4002" />
+ <target name="n3" xsi:type="Network" address="tcp://localhost:4003" />
+ </targets>
+ </nlog>
+ ]]>
+ </code>
+ <p>
+ In the above example we've defined two <u>buffered</u> File targets and three <u>asynchronous and retrying</u> Network
+ targets.
+ </p>
+
+ <h4>Default target parameters</h4>
+ <p>
+ Similar to default wrappers NLog provides <x><default-target-parameters /></x> which enables you to specify default values
+ of target parameters. For example, if you don't want files to be kept open, you can either add keepFileOpen="false" to
+ each target, as in the following example:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <nlog>
+ <targets>
+ <target name="f1" xsi:type="File" fileName="f1.txt" keepFileOpen="false" />
+ <target name="f2" xsi:type="File" fileName="f2.txt" keepFileOpen="false" />
+ <target name="f3" xsi:type="File" fileName="f3.txt" keepFileOpen="false" />
+ </targets>
+ </nlog>
+ ]]>
+ </code>
+ <p>
+ Alternatively you can specify a single <x><default-target-parameters /></x> that applies to all targets in the <x><targets /></x> section. Default
+ parameters are defined on a per-type basis and are applied BEFORE the actual attributes defined in the XML file:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <nlog>
+ <targets>
+ <default-target-parameters xsi:type="File" keepFileOpen="false" />
+ <target name="f1" xsi:type="File" fileName="f1.txt" />
+ <target name="f2" xsi:type="File" fileName="f2.txt" />
+ <target name="f3" xsi:type="File" fileName="f3.txt" />
+ </targets>
+ </nlog>
+ ]]>
+ </code>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
+
diff --git a/web/documentation.xml b/web/documentation.xml
new file mode 100644
index 0000000..9a547b6
--- /dev/null
+++ b/web/documentation.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation">
+ <h1>Documentation</h1>
+
+ <ul>
+ <li><link href="tutorial">Tutorial</link> - <i>"Introduction to NLog"</i></li>
+ <li><link href="wprowadzenie">Tutorial in Polish</link> - <i>"Wprowadzenie do ledzenia aplikacji przy pomocy NLoga"</i></li>
+ <li><link href="config">Configuration File</link> - how to configure logging</li>
+ <li><link href="visualstudio">Visual Studio Support</link> - snippets, Intellisense(TM) and more</li>
+ <li><link href="performance">Performance</link> - how fast is NLog?</li>
+ <li><link href="releasenotes">Release Notes</link></li>
+ </ul>
+ <h3>Reference</h3>
+ <ul>
+ <li><link href="netapi">.NET API</link> - native API</li>
+ <li><link href="capi">C/C++ API</link> - a wrapper API to be used in legacy COM applications</li>
+ <li><link href="comapi">COM API</link> - a wrapper API to be used in legacy C/C++ applications</li>
+ </ul>
+ <ul>
+ <li><link href="targets">Targets</link> - this is where trace output goes</li>
+ <li><link href="layouts">Layouts</link> - output formats (plain text, XML, CSV)</li>
+ <li><link href="layoutrenderers">Layout Renderers</link> - specify things that should be included in output (date, time, class, method, ...)</li>
+ <li><link href="filters">Filters</link> - eliminate messages</li>
+ <li><link href="conditions">Conditions</link> - simple predicate language to filter messages</li>
+ </ul>
+ <h3>How to...</h3>
+ <ul>
+ <li><link href="howto_write_target">How to write your own Target</link></li>
+ <li><link href="howto_write_layout_renderer">How to write your own Layout Renderer</link></li>
+ <li><link href="howto_write_filter">How to write your own Filter</link></li>
+ <li><link href="howto_write_condition_function">How to write your own Condition Function</link></li>
+ <li><link href="howto_optimize_performance">How to optimize logging performance</link></li>
+ <li><link href="howto_troubleshoot">How to troubleshoot your logging problems</link></li>
+ </ul>
+ <last-changed-date>$LastChangedDate: 2006-09-15 22:00:07 +0200 (Pt, 15 wrz 2006) $</last-changed-date>
+</content>
diff --git a/web/download.xml b/web/download.xml
new file mode 100644
index 0000000..56d0b3e
--- /dev/null
+++ b/web/download.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="download">
+ <h1>Downloading NLog</h1>
+ <p>
+ NLog is an open source software, so the source code is available to public and everyone
+ can join the project to improve it. Source and binary packages are available.
+ </p>
+ <ul>
+ <li><a href="http://sourceforge.net/project/showfiles.php?group_id=116456">Download official packages from SourceForge.net</a></li>
+ <li><a href="http://www.nlog-project.org/snapshots/">Development snapshots</a> (updated more frequently, primarily meant for testing, usually as stable as the released packages)</li>
+ <li><a nomangle="1" href="http://svn.nlog-project.org/repos/nlog/trunk/NLog">Subversion repository</a> - to get the most up-to-date source code and build it yourself</li>
+ </ul>
+
+ <p>
+ Subversion is available to everybody in read-only mode. Write access is available <link href="mailinglists">on request</link>.
+ Source code snapshots (in ZIP format) are automatically generated on each commit and are available <a href="http://svn.nlog-project.org/snapshots/">here</a>.
+ </p>
+
+ <p>
+ NLog can be built with either Visual Studio.NET 2003, Visual Studio 2005 or <a href="http://nant.sourceforge.net/">NAnt 0.85</a>.
+ To build NLog using NAnt, just type <code>nant</code> at the command prompt.
+ To rebuild NLog using VS.NET, open the solution file that matches the Visual Studio
+ version you use (<code>NLog.vs2003.sln</code> or <code>NLog.vs2005.sln</code>)
+ and run <code>Build|Rebuild Solution</code>.
+ </p>
+ <last-changed-date>$LastChangedDate: 2006-09-15 22:00:07 +0200 (Pt, 15 wrz 2006) $</last-changed-date>
+</content>
diff --git a/web/faq.xml b/web/faq.xml
new file mode 100644
index 0000000..8fbfbf6
--- /dev/null
+++ b/web/faq.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="faq">
+ <h1>Frequently Asked Questions</h1>
+ <faq-index />
+
+ <faq>
+ <faq-question>How do I properly log exceptions?</faq-question>
+ <faq-answer>
+ <p>
+ Exceptions require special treatment in NLog.
+ You need to call a Logger method which takes Exception as its second argument. The method names match available log levels:
+ </p>
+
+ <ul>
+ <li><b>TraceException()</b></li>
+ <li><b>DebugException()</b></li>
+ <li><b>InfoException()</b></li>
+ <li><b>WarnException()</b></li>
+ <li><b>ErrorException()</b></li>
+ <li><b>FatalException()</b></li>
+ <li><b>LogException()</b> - takes log level as a parameter</li>
+ </ul>
+
+ <p>
+ Typically you call one of these methods in the <code>catch</code> handler:
+ </p>
+
+ <code lang="C#">
+ <![CDATA[
+ try
+ {
+ // some code which may throw
+ }
+ catch (MyException ex)
+ {
+ logger.ErrorException("Got exception.", ex);
+ }
+ ]]>
+ </code>
+ <p>
+ To write the details of the exception, use the <code>${exception}</code> <a href="lr.exception.html">layout renderer</a> in
+ your layout. Depending on the desired output you may want to specify different value for the "format" argument. The
+ following example displays the result of calling <code>ToString()</code> on the exception object.
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <nlog>
+ <targets>
+ <target name="f" type="File" layout="${longdate} ${message} ${exception:format=tostring}" />
+ </targets>
+ <rules>
+ <logger name="*" writeTo="f" />
+ </rules>
+ </nlog>
+ ]]>
+ </code>
+ </faq-answer>
+ </faq>
+ <faq>
+ <faq-question>How do I configure logging for a component?</faq-question>
+ <faq-answer>
+ <p>
+If you can configure logging on the client-side (by providing the appropriate configuration file in application's directory), you can
+follow the <link href="tutorial">tutorial</link>.
+</p>
+
+<p>
+However, if you do not control the clients, or they are
+not all local, or you wish a solution encapsulated to your
+component or assembly, you may wish to configure logging
+locally in your component assembly.
+</p>
+
+<p>
+ The solution is to create a log manager just for your component that will manage its own loggers. You need to load the configuration
+ file by hand and/or configure logging programmatically but your configuration will be independent from application's config.
+</p>
+
+<p>The following solution is usable for components not in the GAC. (Components in the GAC need to implement below method GetNLogConfigFilepath in some
+ application-dependent fashion.)</p>
+
+<code lang="C#">
+ internal class MyLogManager
+ {
+ // A Logger dispenser for the current assembly
+ public static readonly LogFactory Instance
+ = new LogFactory(new XmlLoggingConfiguration(GetNLogConfigFilePath()));
+
+ //
+ // Use a config file located next to our current assembly dll
+ // eg, if the running assembly is c:\path\to\MyComponent.dll
+ // the config filepath will be c:\path\to\MyComponent.nlog
+ //
+ // WARNING: This will not be appropriate for assemblies in the GAC
+ //
+ private static string GetNLogConfigFilePath()
+ {
+ // Use name of current assembly to construct NLog config filename
+
+ Assembly thisAssembly = Assembly.GetExecutingAssembly();
+
+ return Path.ChangeExtension(thisAssembly.Location, ".nlog");
+ }
+ }
+</code>
+
+Then create loggers with:
+
+<code lang="C#">
+ Logger logger = MyLogManager.Instance.GetLogger("name");
+</code>
+
+or
+
+<code lang="C#">
+ Logger logger = MyLogManager.Instance.GetCurrentClassLogger();
+</code>
+
+<p>
+ The loggers are independent from the ones created with NLog
+ LogManager, and thus you can have safe private logging. That is,
+ this will not interfere with other assemblies or the application
+ exe itself using NLog.
+</p>
+
+<p>
+ If you want multiple assemblies to share this MyLogManager -
+ just make it a public class and get others to use it.
+</p>
+
+<p>
+ You need to make sure that the configuration is properly
+closed when the process terminates (set
+MyLogManager.Instance.Configuration to null) or you may
+lose some log output.
+
+You may want to hook AppDomain.ProcessExit and
+AppDomain.DomainUnload events to turn off logging automatically.
+
+See the code of <a href="http://svn.nlog-project.org/repos/nlog/trunk/NLog/src/NLog/LogManager.cs">LogManager.cs</a> for details.
+</p>
+ </faq-answer>
+ </faq>
+ <last-changed-date>$LastChangedDate: 2006-07-18 19:44:49 +0200 (Wt, 18 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/favicon.ico b/web/favicon.ico
new file mode 100644
index 0000000..94bd9f2
Binary files /dev/null and b/web/favicon.ico differ
diff --git a/web/filters.xsl b/web/filters.xsl
new file mode 100644
index 0000000..f24f2e8
--- /dev/null
+++ b/web/filters.xsl
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:include href="style.xsl" />
+ <xsl:param name="filter_name" />
+
+ <xsl:template match="*" mode="content">
+ <xsl:if test="not($filter_name)">
+ <h1>Log Filters</h1>
+ <p>
+ The following filters are available. Click on a name for full reference.
+ </p>
+ <div class="noborder">
+ <table class="listtable">
+ <xsl:call-template name="supportmatrixheader" />
+ <xsl:apply-templates select="//class[attribute/@name='NLog.FilterAttribute']" mode="list">
+ <xsl:sort select="attribute[@name='NLog.FilterAttribute']/property[@name='Name']/@value" />
+ </xsl:apply-templates>
+ </table>
+ </div>
+ </xsl:if>
+ <xsl:if test="$filter_name">
+ <xsl:apply-templates select="//class[attribute/@name='NLog.FilterAttribute' and attribute/property[@name='Name']/@value=$filter_name]" mode="details">
+ <xsl:sort select="attribute[@name='NLog.FilterAttribute']/property[@name='Name']/@value" />
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="class" mode="list">
+ <xsl:variable name="type_tag" select="attribute[@name='NLog.FilterAttribute']/property[@name='Name']/@value" />
+ <tr>
+ <td class="name"><a href="filter.{$type_tag}.html"><xsl:value-of select="$type_tag" /></a></td>
+ <td class="description"><xsl:apply-templates select="documentation/summary" /></td>
+ <xsl:call-template name="supportmatrixvalues" />
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="@* | node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@* | node()" />
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="summary">
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="class" mode="details">
+ <xsl:variable name="type_tag" select="attribute[@name='NLog.FilterAttribute']/property[@name='Name']/@value" />
+ <h3><xsl:value-of select="$type_tag" /> Filter</h3>
+ <hr size="1" />
+ <xsl:apply-templates select="documentation/summary" /><p/>
+ <xsl:call-template name="detailssupportmatrix" />
+ <xsl:if test="documentation/remarks">
+ <h4>Remarks</h4>
+ <xsl:apply-templates select="documentation/remarks" /><p/>
+ </xsl:if>
+ <h4>Parameters:</h4>
+ <table class="paramtable">
+ <tr>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+ <xsl:apply-templates select="property" mode="parameter">
+ <xsl:sort select="count(attribute[@name='NLog.Config.RequiredParameterAttribute'])" order="descending" />
+ <xsl:sort select="@name" />
+ </xsl:apply-templates>
+ </table>
+ <xsl:if test="documentation/example">
+ <h4>Example:</h4>
+ <xsl:apply-templates select="documentation/example" />
+ </xsl:if>
+ <hr size="1" />
+ <a href="filters.html">Back to the filter list.</a>
+ </xsl:template>
+
+ <xsl:template match="property[@set='false']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@name='Name']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@name='Type']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@type='NLog.Layout']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@type='NLog.ILayout']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property" mode="parameter">
+ <tr>
+ <td class="parametername">
+ <span>
+ <xsl:if test="attribute/@name='NLog.Config.RequiredParameterAttribute'">
+ <xsl:attribute name="class">required</xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="@name" />
+ </span>
+ </td>
+ <td class="parametertype">
+ <nobr>
+ <xsl:call-template name="simple-type-name">
+ <xsl:with-param name="type" select="@type" />
+ </xsl:call-template>
+ <xsl:if test="attribute/@name='NLog.Config.AcceptsLayoutAttribute'">
+ <a href="layoutrenderers.html"><span class="acceptslayout" title="This parameter accepts layout specification. Click here to learn more about layouts.">${}</span></a>
+ </xsl:if>
+ </nobr>
+ </td>
+ <td class="parametervalue">
+ <xsl:apply-templates select="documentation/summary" />
+ <br/>
+ <xsl:if test="attribute[@name='System.ComponentModel.DefaultValueAttribute']">
+ <p>Default value is: <code><xsl:value-of select="attribute[@name='System.ComponentModel.DefaultValueAttribute']/property[@name='Value']/@value" /></code>.</p>
+ </xsl:if>
+ <xsl:if test="documentation/remarks">
+ <h4>Remarks</h4>
+ <p><xsl:apply-templates select="documentation/remarks" /></p>
+ </xsl:if>
+ <xsl:if test="documentation/example">
+ <h4>Example</h4>
+ <p><xsl:apply-templates select="documentation/example" /></p>
+ </xsl:if>
+ </td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="property[attribute/@name='NLog.Config.ArrayParameterAttribute']" mode="parameter2">
+ <xsl:variable name="itemtype" select="attribute[@name='NLog.Config.ArrayParameterAttribute']/property[@name='ElementType']/@value" />
+ <br/><<xsl:value-of select="@name" />><br/>
+ <xsl:value-of select="$itemtype" />
+ <xsl:apply-templates select="//class[@name='$itemtype']" mode="parameter" />
+ </<xsl:value-of select="@name" />>
+ </xsl:template>
+
+ <xsl:template match="property" mode="parameter2">
+ </xsl:template>
+
+ <xsl:template match="c">
+ <code><xsl:apply-templates /></code>
+ </xsl:template>
+
+ <xsl:template match="code">
+ <code><pre class="example"><xsl:apply-templates /></pre></code>
+ </xsl:template>
+
+ <xsl:template match="see">
+ <code><xsl:value-of select="@cref" /></code>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/web/forum.xml b/web/forum.xml
new file mode 100644
index 0000000..5c4c073
--- /dev/null
+++ b/web/forum.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="support" subid="forum">
+ <h1>Nabble Forum</h1>
+</content>
diff --git a/web/help.menu b/web/help.menu
new file mode 100644
index 0000000..c60068d
--- /dev/null
+++ b/web/help.menu
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<common>
+ <navigation>
+ <nav href="helpindex" label="Introduction" />
+ <nav href="documentation" label="Documentation" />
+ <nav href="faq" label="FAQ" />
+ <nav href="http://www.nabble.com/NLog-Forum-f6167.html" noext="true" label="Forum" />
+ <nav href="http://trac.nlog-project.org/nlog/" noext="true" label="Issue Tracker" />
+ <nav href="mailinglists" label="Mailing Lists" />
+ </navigation>
+</common>
diff --git a/web/helpindex.xml b/web/helpindex.xml
new file mode 100644
index 0000000..c5c5fdf
--- /dev/null
+++ b/web/helpindex.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="helpindex">
+ <h3>What is NLog?</h3>
+ <p>
+ NLog is a .NET logging library similar in concepts to <a href="http://logging.apache.org/log4net/">log4net</a>,
+ designed with simplicity and flexibility in mind.
+ </p>
+
+ <h3>Features</h3>
+ <ul>
+ <li>.NET, .NET Compact Framework and Mono 1.0 support</li>
+ <li>very easy to configure, both with a config file and programmatically</li>
+ <li>easy to use - interface is identical to <code>Console.WriteLine</code> - there's no need to use <code>String.Format</code> any more</li>
+ <li>supports <link href="netapi">.NET</link>, <link href="capi">C/C++</link> and <link href="comapi">COM</link> interop API</li>
+ </ul>
+ <p>
+ NLog is open source, licensed
+ under the terms of <a href="http://www.opensource.org/licenses/bsd-license.php">BSD license</a>,
+ which permits commercial use. Everyone is encouraged to test it and report feedback to the mailing list.
+ </p>
+ <p>
+ The logging API is modelled after log4net with some extensions that help it achieve great speed as described <link href="netapi">here</link>.
+ </p>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/howto.xml b/web/howto.xml
new file mode 100644
index 0000000..cfed90e
--- /dev/null
+++ b/web/howto.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" subid="howto">
+ <h1>How To...</h1>
+ <ol>
+ <li><link href="howto_write_target">How to write your own log Target</link></li>
+ <li><link href="howto_write_layout_renderer">How to write your own Layout Renderer</link></li>
+ <li><link href="howto_write_filter">How to write your own Filter</link></li>
+ <li><link href="howto_write_condition_function">How to write your own Condition Function</link></li>
+ <li><link href="howto_optimize_performance">How to optimize logging performance</link></li>
+ <li><link href="howto_troubleshoot">How to troubleshoot your logging problems</link></li>
+ </ol>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/howto_optimize_performance.xml b/web/howto_optimize_performance.xml
new file mode 100644
index 0000000..34b9bd4
--- /dev/null
+++ b/web/howto_optimize_performance.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" subid="howto">
+ <h1>How to optimize logging performance</h1>
+
+ <h4>Overview</h4>
+ <p>Logging can take a considerable amount of time. This document helps you understand why it happens so
+ and provides some performance tips that can speed up your logging.
+ </p>
+ <h4>Logging process described</h4>
+ <p>
+ Every time you use log a message several things need to be done to check if the message is
+ to be logged, and where to write the output to. Each call to <code>Debug, Info, Warn, Error,
+ Fatal</code> or the generic <code>Log</code> incolves the following operations:
+ </p>
+ <ol>
+ <li>The logging parameters are prepared. This is the job of a CLI runtime (.NET/Mono) and may introduce some considerable overhead - in most cases related to boxing or hidden array construction.</li>
+ <li>The appropriate logging method (<code>Debug(), Info(), Warn(), Error(), Fatal()</code> or <code>Log()</code>) is called with the prepared parameters.</li>
+ <li>The logging method roughly checks if the output is enabled for the specified logger at
+ the specified level. This is done very quickly (a single comparison) because of the data structures used.</li>
+ <li>If the previous check succeeded, there's still a chance that the message will not get logged
+ - in this step <a href="filters.html">filters</a> are evaluated and they have a chance to reject the method.
+ Note that filters can be expensive in terms of the time of execution.</li>
+ <li>After the message is qualified to be logged - the log message is formatted based on message and parameters
+ passed to the logging function. This can be pretty slow because the <code>String.Format</code>
+ isn't very fast.</li>
+ <li>The last step is passing the log event to one or more targets so that they can
+ to write the event to output. This is usually the most time-consuming part of the process because
+ targets are typically some kind of persistent storage (file, database) and it takes time
+ to write to such outputs.</li>
+ </ol>
+ <p>
+ "<i>This is bad news...</i>", you might think, but fortunately NLog provides many mechanisms that help
+ speed up your logging.
+ </p>
+ <h3>Performance Tips</h3>
+ <h4>Cache your logger instance</h4>
+ <p>Once you get your logger from <code>LogManager.GetLogger()</code> it's advised to store the reference
+ somewhere and reuse it without calling <code>LogManager.GetLogger()</code> again. A static member to your
+ class is quite a good idea. The following example describes it:
+ </p>
+ <code lang="C#" src="examples/web/Performance.cs" />
+ <p style="class: red">TODO: add more tips here</p>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/howto_troubleshoot.xml b/web/howto_troubleshoot.xml
new file mode 100644
index 0000000..285c3b2
--- /dev/null
+++ b/web/howto_troubleshoot.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" subid="howto">
+ <h1>How to troubleshoot logging problems</h1>
+ <p>If you have trouble getting NLog to work properly you may want to enable some debugging
+ output to see what may be going wrong. This document describes the available internal debugging
+ features of NLog.</p>
+ <h4>Enabling internal logging</h4>
+ The following variables can be used to control NLog internal debugging:
+ <p><code>NLOG_INTERNAL_LOG_TO_CONSOLE</code> - if this variable is found in the environment
+ NLog outputs internal logging information to the console using <code>Console.WriteLine</code>.</p>
+ <p><code>NLOG_INTERNAL_LOG_FILE</code> - if this variable is found in the environment
+ NLog outputs internal logging information to the specified file. The file must be writable
+ by the current user or it will not be created.</p>
+ <p><code>NLOG_INTERNAL_LOG_LEVEL</code> - sets the internal logging level. The available values
+ are <code>Debug, Info, Warn, Error, Fatal</code> - the default is <code>Info</code> which should
+ be appropriate for most cases, to get more detailed logging - set it to <code>Debug</code>.</p>
+ <h4>Enabling internal logging using the environment variables</h4>
+ There are two cases here - setting the variables for an interactive process or for a service process.
+ <h5>Enabling internal logging in the interactive processes</h5>
+ <p>This case is easy. Just open the command prompt (<code>cmd.exe</code>), set your variables using
+ the SET command and run your program. Here's the example:
+ </p>
+ <pre style="background-color: black; color: yellow; font-family: Courier New;padding: 10px; width: 80%">
+ Microsoft Windows [Version 5.2.3790]
+ (C) Copyright 1985-2003 Microsoft Corp.
+
+ C:\MyApp>set NLOG_INTERNAL_LOG_FILE=c:\temp\mylog.txt
+
+ C:\MyApp>set NLOG_INTERNAL_LOG_LEVEL=Debug
+
+ C:\MyApp>myapp.exe
+ </pre>
+ <h5>Enabling internal logging in the service processes</h5>
+ <p>TO BE WRITTEN</p>
+
+ <h4>Enabling internal logging programmatically</h4>
+ <p>TO BE WRITTEN</p>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/howto_write_condition_function.xml b/web/howto_write_condition_function.xml
new file mode 100644
index 0000000..973bb5b
--- /dev/null
+++ b/web/howto_write_condition_function.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" subid="howto">
+ <h1>How to write your own Condition Function</h1>
+
+ <p>
+ To be written.
+ </p>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
+
diff --git a/web/howto_write_filter.xml b/web/howto_write_filter.xml
new file mode 100644
index 0000000..970bf31
--- /dev/null
+++ b/web/howto_write_filter.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" subid="howto">
+ <h1>How to write your own Filter</h1>
+
+ <h5>Why would I want to write a Filter?</h5>
+
+ <p>Filters are a way to eliminate unnecessary logging messages and prevent them
+ from reaching log <link href="targets">targets</link>. NLog comes with
+ pre-defined filters that operate on string layouts and support most
+ common operators. You need your own filter if none of the <link href="filters">provided filters</link>
+ are suitable for your purpose.
+ </p>
+
+ <h5>How to write a filter?</h5>
+ <p>
+ It's really easy. Create a class that inherits from <code>NLog.Filter</code>
+ and override the <code>Check()</code> method. This method should return one of the following:
+ </p>
+ <p>
+ <ul>
+ <li><code>FilterResult.Neutral</code> - The filter doesn't want to decide whether the message should be logged. Further filters (if any) should be invoked to check.</li>
+ <li><code>FilterResult.Ignore</code> - The message should NOT be logged</li>
+ <li><code>FilterResult.Log</code> - The message should be logged. No further filters will be invoked.</li>
+ </ul>
+ </p>
+ <p>
+ Typically it's up to the user to decide what to do with the message after the filter matches.
+ Each filter has a <code>Result</code> that contains user-requested filter result for such a case. Filters
+ that would like to support user-configurability should return <code>Result</code> or <code>FilterResult.Neutral</code>.
+ </p>
+
+ <h5>Example</h5>
+ <p>This is an example filter that eliminates messages sent between the specified hours.</p>
+ <p>
+ <code>csc.exe /t:library /out:MyAssembly.dll /r:NLog.dll MyFirstFilter.cs</code>
+ </p>
+
+ <code lang="C#" src="examples/web/MyFirstFilter.cs" />
+
+ <h5>How to use the newly created layout renderer?</h5>
+ <p>
+ It's easy. Just put the renderer in a DLL and reference it from the the config file using the <x><extensions /></x>
+ clause as described <a href="config.html#extensions">here</a>.
+ </p>
+
+ <h5>Configuration file example</h5>
+ <p>
+ This example causes all messages between 10:00 and 12:59 to be ignored. Simple isn't it?
+ </p>
+
+ <code lang="xml" src="examples/web/config10.nlog" />
+
+ <h5>How to pass configuration options to the filter?</h5>
+
+ <p>
+ Consider the above example. There are properties called "FromHour" and "ToHour" that do just that.
+ Having a public property that sets the required configuration parameters is enough for NLog to use it.
+ Each attribute that you put in the filter definition gets passed to the appropriate public property.
+ NLog takes care of the appropriate conversions necessary so that you can use integer, string, datetime,
+ boolean parameters. The parameters are case-insensitive.
+ </p>
+
+ <x><filters> ... <hourRange fromHour="10" toHour="12" action="Ignore" /> ... </filters></x>
+
+ <p>sets the FromHour property to 10 and ToHour to 12 during configuration. To pass more parameters, just use more attributes:</p>
+
+ <x><filters> ... <hourRange p1="" p2="" p3="" p4="" pN="" action="Ignore" /> ... </filters></x>
+
+ <h5>Do I really need to create a separate DLL?</h5>
+
+ <p>
+ Not really. You can use FilterFactory.AddFilter() to register your layout renderer programmatically.
+ Just be sure to to it at the very beginning of your program before any log messages are written.
+ It should be possible to reference your EXE using the <x><extensions /></x> clause.
+ </p>
+
+ <code lang="C#" src="examples/web/AddFilter.cs" />
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
+
diff --git a/web/howto_write_layout_renderer.xml b/web/howto_write_layout_renderer.xml
new file mode 100644
index 0000000..ca40b99
--- /dev/null
+++ b/web/howto_write_layout_renderer.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" subid="howto">
+ <h1>How to write your own Layout Renderer</h1>
+
+ <h5>Why would I want to write a Layout Renderer?</h5>
+
+ <p>Layout renderers are a way to enrich your debugging output by outputting
+ environmental properties of your applications. NLog comes with Layout Renderers for most common tasks (like
+ outputting environment variables, registry keys, thread ids, base directory, etc.),
+ but you may want to develop your own Layout Renderer to provide information about your
+ application or framework.
+ </p>
+
+ <h5>How to write a layout renderer?</h5>
+ <p>
+ It's really easy. Create a class that inherits from <code>NLog.LayoutRenderer</code>
+ and override the <code>Append()</code> method. In the body of the method use the
+ <code>ApplyPadding()</code> to get the output text formatted according to the
+ common Layout Renderer parameters then send the text to the destination <code>StringBuilder</code>.
+ </p>
+
+ <h5>Example</h5>
+ <p>This is a skeleton layout renderer that outputs current hour. Compile using:</p>
+ <p>
+ <code>csc.exe /t:library /out:MyAssembly.dll /r:NLog.dll MyFirstLayoutRenderer.cs</code>
+ </p>
+
+ <code lang="C#" src="examples/web/MyFirstLayoutRenderer.cs" />
+
+<h5>How to use the newly created layout renderer?</h5>
+<p>
+ It's easy. Just put the renderer in a DLL and reference it from the the config file using the <x><extensions /></x>
+ clause as described <a href="config.html#extensions">here</a>.
+</p>
+
+<h5>Configuration file example</h5>
+<p>
+ This example causes all messages written to the console to be prepended with current hour. Simple isn't it?
+</p>
+
+<code lang="XML" src="examples/web/config9.nlog" />
+
+<h5>How to pass configuration options to the renderer?</h5>
+
+<p>
+Consider the above example. There's a property called "ShowMinutes" that does just that.
+Having a public property that sets the required configuration parameters is enough for NLog to use it.
+Parameters can be passed by separating them with colons. For example:
+</p>
+
+<code>${hour:showminutes=true}</code>
+
+<p>sets the ShowMinutes property to True during configuration. To pass more parameters, just use more colons:</p>
+
+<code>${layoutrenderername:par1=value1:par2=value2:par3=value3:...:parN=valueN}</code>
+<p>
+NLog takes care of the appropriate conversions necessary so that
+you can use integer, string, datetime, boolean parameters.
+</p>
+
+<h5>Do I really need to create a separate DLL?</h5>
+
+<p>
+ Not really. You can use LayoutRendererFactory.AddLayoutRenderer() to register your layout renderer programmatically.
+ Just be sure to to it at the very beginning of your program before any log messages are written.
+ It should be possible to reference your EXE using the <x><extensions /></x> clause.
+</p>
+
+<code lang="C#" src="examples/web/AddLayoutRenderer.cs" />
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
+
diff --git a/web/howto_write_target.xml b/web/howto_write_target.xml
new file mode 100644
index 0000000..05f142d
--- /dev/null
+++ b/web/howto_write_target.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" subid="howto">
+ <h1>How to write your own Target</h1>
+
+ <h5>Why would I want to write a Target?</h5>
+
+ <p>If you want to write your trace messages to some non-standard output (for example to some management tool or over the network or using the PPPoP (<a href="http://www.notes.co.il/benbasat/5240.asp">PPP-over-pigeon</a> protocol) you need to write a custom Target.</p>
+
+ <h5>How to write a target?</h5>
+ <p>
+ It's really easy. Create a class that inherits from <code>NLog.TargetWithLayout</code> (or
+ <code>NLog.Target</code> if you don't want to use <code>layout</code>) and override
+ the <code>Write(LogEventInfo)</code> method. In the body of the method use
+ <code>CompiledLayout.GetFormattedMessage()</code> to get the message text, then send the text to the destination media.
+ </p>
+ <p>
+ If your target can optimize for batch writes you should also override the <code>Write(LogEventInfo[])</code> method.
+ </p>
+
+ <h5>Example</h5>
+ <p>This is a skeleton target that writes messages to the specified host. Compile using:</p>
+ <p>
+ <code>csc.exe /t:library /out:MyAssembly.dll /r:NLog.dll MyFirstTarget.cs</code>
+ </p>
+
+ <code lang="C#" src="examples/web/MyFirstTarget.cs" />
+
+<h5>How to use the newly created target?</h5>
+<p>
+
+ It's easy. Just put the target in a DLL and reference it from the the config file using the <x><extensions /></x>
+ clause as described <a href="config.html#extensions">here</a>.
+</p>
+
+<h5>Configuration file example</h5>
+
+<code lang="XML" src="examples/web/config7.nlog" />
+
+<h5>How to pass configuration options to the target?</h5>
+
+<p>
+Consider the above example. There's a property called "Host" that does just that.
+Having a public property that sets the required configuration parameters is enough for NLog to use it.
+Each attribute that you put in the <x><target /></x> definition gets passed
+to the appropriate public property. NLog takes care of the appropriate conversions necessary so that
+you can use integer, string, datetime, boolean parameters.
+</p>
+
+<h5>Do I really need to create a separate DLL?</h5>
+
+<p>
+ Not really. You can use TargetFactory.AddTarget() to register your target programmatically.
+ Just be sure to to it at the very beginning of your program before any log messages are written.
+ It should be possible to reference your EXE using the <x><extensions /></x> clause.
+</p>
+
+<code lang="C#" src="examples/web/AddTarget.cs" />
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
+
diff --git a/web/introduction.xml b/web/introduction.xml
new file mode 100644
index 0000000..aa1e7b3
--- /dev/null
+++ b/web/introduction.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="introduction">
+ <h1>Introduction to NLog</h1>
+ <p>
+ NLog is a .NET logging library designed with simplicity and flexibility in mind. With NLog you
+ can process diagnostic messages emitted from any .NET language, augment them with
+ <link href="layoutrenderers">contextual information</link>, format them according to your preference
+ and send them to one or more <link href="targets">targets</link>.
+ </p>
+ <p>
+ The <link href="netapi">API</link> (application programming interface) is similar
+ to <a href="http://logging.apache.org/log4net/">log4net</a>, and the configuration is very simple.
+ NLog uses a <link href="config">routing table</link> while log4net uses a logger hierarchy
+ with attachable appenders. This makes NLog's configuration very easy to read and maintain.
+ </p>
+ <p>
+ NLog is licensed under the terms of <a href="http://svn.nlog-project.org/repos/nlog/trunk/NLog/LICENSE.txt">BSD license</a>,
+ which permits commercial use and the source code is available to anyone at no cost.
+ Everyone is encouraged to test it and report feedback to the mailing list.
+ </p>
+
+ <p>
+ NLog supports <link href="netapi">.NET</link>, <link href="capi">C/C++</link> and <link href="comapi">COM</link> interop API
+ so that all your application components including legacy modules written in C++/COM can send their messages through
+ a common log routing engine.
+ </p>
+ <p>
+ The .NET API is very fast at filtering messages, so that you can keep your logging instructions in code
+ and let NLog filter them out at runtime. NLog can filter out as many as 150 million logging instructions
+ per second on a single-CPU 1.6 GHz laptop. Add that to <a href="target.AsyncWrapper.html">asynchronous processing</a> and
+ other <a href="targets.html#wrappers">wrappers</a> and you'll get a very powerful and scalable logging tool.
+ </p>
+
+ <h3>Recent News</h3>
+ <p>2006-09-18: <b style="color: red">NLog 1.0 has been released</b>.
+ Release notes can be found <link href="releasenotes">here</link>.
+ </p>
+ <p>2006-06-27: NLog 1.0 Release Candidate 1 is available. Release notes can be found <link href="releasenotes">here</link>. The highlights of this release are:
+ <ul>
+ <li><link href="visualstudio">Visual Studio 2005 Integration</link>. Flash screencast (22 MB) is <a href="http://www.nlog-project.org/demos/NLogDemo1.html">here</a>.</li>
+ <li>Ready-to-run <a href="http://svn.nlog-project.org/repos/nlog/trunk/NLog/examples/targets/">example projects for VS2005</a>.</li>
+ <li>Optimized <a href="target.File.html">File</a> target that can write to multiple files at once from multiple processes while keeping the files open.</li>
+ <li>Automatic <a href="target.File.html">archiving of log files</a></li>
+ <li>New <a href="target.WebService.html">WebService</a> and <a href="target.CSVFile.html">CSVFile</a> targets.</li>
+ <li>Even more speed improvements in the non-logging area.</li>
+ </ul>
+ </p>
+ <last-changed-date>$LastChangedDate: 2006-09-18 14:32:45 +0200 (Pn, 18 wrz 2006) $</last-changed-date>
+</content>
diff --git a/web/introduction_addnewitem.gif b/web/introduction_addnewitem.gif
new file mode 100644
index 0000000..4a6c97a
Binary files /dev/null and b/web/introduction_addnewitem.gif differ
diff --git a/web/introduction_coloredconsole.gif b/web/introduction_coloredconsole.gif
new file mode 100644
index 0000000..353fd1f
Binary files /dev/null and b/web/introduction_coloredconsole.gif differ
diff --git a/web/introduction_coloredconsole_en.gif b/web/introduction_coloredconsole_en.gif
new file mode 100644
index 0000000..89416ae
Binary files /dev/null and b/web/introduction_coloredconsole_en.gif differ
diff --git a/web/introduction_copytooutput.gif b/web/introduction_copytooutput.gif
new file mode 100644
index 0000000..c10e274
Binary files /dev/null and b/web/introduction_copytooutput.gif differ
diff --git a/web/introduction_target_intellisense.gif b/web/introduction_target_intellisense.gif
new file mode 100644
index 0000000..ba1adc7
Binary files /dev/null and b/web/introduction_target_intellisense.gif differ
diff --git a/web/lang_pl.gif b/web/lang_pl.gif
new file mode 100644
index 0000000..c862f82
Binary files /dev/null and b/web/lang_pl.gif differ
diff --git a/web/layoutrenderers.xsl b/web/layoutrenderers.xsl
new file mode 100644
index 0000000..aa92183
--- /dev/null
+++ b/web/layoutrenderers.xsl
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:include href="style.xsl" />
+
+ <xsl:param name="lr_name" />
+
+ <xsl:template match="*" mode="content">
+ <xsl:if test="not($lr_name)">
+ <h1>Layout Renderers</h1>
+ <p>
+ The following layout renderers are available. Click on a name for full reference.
+ </p>
+ <div class="noborder">
+ <table class="listtable">
+ <xsl:call-template name="supportmatrixheader" />
+ <xsl:apply-templates select="//class[attribute/@name='NLog.LayoutRendererAttribute']" mode="list">
+ <xsl:sort select="../../@name" />
+ <xsl:sort select="attribute[@name='NLog.LayoutRendererAttribute']/property[@name='FormatString']/@value" />
+ </xsl:apply-templates>
+ </table>
+ </div>
+ </xsl:if>
+ <xsl:if test="$lr_name">
+ <xsl:apply-templates select="//class[attribute/@name='NLog.LayoutRendererAttribute' and attribute/property[@name='FormatString']/@value=$lr_name]" mode="details">
+ <xsl:sort select="../../@name" />
+ <xsl:sort select="attribute[@name='NLog.LayoutRendererAttribute']/property[@name='FormatString']/@value" />
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="class" mode="list">
+ <xsl:variable name="type_tag" select="attribute[@name='NLog.LayoutRendererAttribute']/property[@name='FormatString']/@value" />
+ <tr>
+ <td class="name"><a href="lr.{$type_tag}.html"><xsl:value-of select="$type_tag" /></a></td>
+ <td class="description"><xsl:apply-templates select="documentation/summary" /></td>
+ <xsl:call-template name="supportmatrixvalues" />
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="@* | node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@* | node()" />
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="summary">
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="class" mode="details">
+ <xsl:variable name="type_tag" select="attribute[@name='NLog.LayoutRendererAttribute']/property[@name='FormatString']/@value" />
+ <xsl:variable name="ignoresPadding" select="attribute[@name='NLog.LayoutRendererAttribute']/property[@name='IgnoresPadding']/@value" />
+ <h3>${<xsl:value-of select="$type_tag" />} Layout Renderer</h3>
+ <hr size="1" />
+ <xsl:apply-templates select="documentation/summary" /><p/>
+ <xsl:call-template name="detailssupportmatrix" />
+ <xsl:if test="property[not(@declaringType='NLog.LayoutRenderer')] or not($ignoresPadding='True')">
+ <h4>Parameters:</h4>
+ <table class="paramtable">
+ <tr>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+ <xsl:apply-templates select="property[not(@declaringType='NLog.LayoutRenderer')]" mode="parameter">
+ <xsl:sort select="count(attribute[@name='NLog.Config.RequiredParameterAttribute'])" order="descending" />
+ <xsl:sort select="@name" />
+ </xsl:apply-templates>
+ <xsl:if test="not($ignoresPadding='True')">
+ <xsl:apply-templates select="property[@declaringType='NLog.LayoutRenderer']" mode="parameter">
+ <xsl:sort select="count(attribute[@name='NLog.Config.RequiredParameterAttribute'])" order="descending" />
+ <xsl:sort select="@name" />
+ </xsl:apply-templates>
+ </xsl:if>
+ </table>
+ </xsl:if>
+ <xsl:if test="documentation/remarks">
+ <h4>Remarks:</h4>
+ <xsl:apply-templates select="documentation/remarks" />
+ </xsl:if>
+ <xsl:if test="documentation/example">
+ <h4>Example:</h4>
+ <xsl:apply-templates select="documentation/example" />
+ </xsl:if>
+ <hr size="1" />
+ <a href="layoutrenderers.html">Back to the layout renderer list.</a>
+ </xsl:template>
+
+ <xsl:template match="property[@set='false']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@name='Name']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@name='Type']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@type='NLog.Layout']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@type='NLog.ILayout']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property" mode="parameter">
+ <xsl:call-template name="parameter_info" />
+ </xsl:template>
+
+ <xsl:template match="property[attribute/@name='NLog.Config.ArrayParameterAttribute']" mode="parameter2">
+ <xsl:variable name="itemtype" select="attribute[@name='NLog.Config.ArrayParameterAttribute']/property[@name='ElementType']/@value" />
+ <br/><<xsl:value-of select="@name" />><br/>
+ <xsl:value-of select="$itemtype" />
+ <xsl:apply-templates select="//class[@name='$itemtype']" mode="parameter" />
+ </<xsl:value-of select="@name" />>
+ </xsl:template>
+
+ <xsl:template match="property" mode="parameter2">
+ </xsl:template>
+
+ <xsl:template match="c">
+ <code><xsl:apply-templates /></code>
+ </xsl:template>
+
+ <xsl:template match="code">
+ <code><pre class="example"><xsl:apply-templates /></pre></code>
+ </xsl:template>
+
+ <xsl:template match="see">
+ <code><xsl:value-of select="@cref" /></code>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/web/layouts.xsl b/web/layouts.xsl
new file mode 100644
index 0000000..07d9cfc
--- /dev/null
+++ b/web/layouts.xsl
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:include href="style.xsl" />
+
+ <xsl:param name="l_name" />
+
+ <xsl:template match="*" mode="content">
+ <xsl:if test="not($l_name)">
+ <h1>Layouts</h1>
+ <p>
+ The following layouts are available.
+ </p>
+ <div class="noborder">
+ <table class="listtable">
+ <xsl:call-template name="supportmatrixheader" />
+ <xsl:apply-templates select="//class[attribute/@name='NLog.LayoutAttribute']" mode="list">
+ <xsl:sort select="../../@name" />
+ <xsl:sort select="attribute[@name='NLog.LayoutAttribute']/property[@name='Name']/@value" />
+ </xsl:apply-templates>
+ </table>
+ </div>
+ </xsl:if>
+ <xsl:if test="$l_name">
+ <xsl:apply-templates select="//class[attribute/@name='NLog.LayoutAttribute' and attribute/property[@name='Name']/@value=$l_name]" mode="details">
+ <xsl:sort select="../../@name" />
+ <xsl:sort select="attribute[@name='NLog.LayoutAttribute']/property[@name='Name']/@value" />
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="class" mode="list">
+ <xsl:variable name="type_tag" select="attribute[@name='NLog.LayoutAttribute']/property[@name='Name']/@value" />
+ <tr>
+ <td class="name"><a href="layout.{$type_tag}.html"><xsl:value-of select="$type_tag" /></a></td>
+ <td class="description"><xsl:apply-templates select="documentation/summary" /></td>
+ <xsl:call-template name="supportmatrixvalues" />
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="@* | node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@* | node()" />
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="summary">
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="class" mode="details">
+ <xsl:variable name="type_tag" select="attribute[@name='NLog.LayoutAttribute']/property[@name='Name']/@value" />
+ <xsl:variable name="ignoresPadding" select="attribute[@name='NLog.LayoutAttribute']/property[@name='IgnoresPadding']/@value" />
+ <h3>${<xsl:value-of select="$type_tag" />} Layout Renderer</h3>
+ <hr size="1" />
+ <xsl:apply-templates select="documentation/summary" /><p/>
+ <xsl:call-template name="detailssupportmatrix" />
+ <xsl:if test="property[not(@declaringType='NLog.Layout')] or not($ignoresPadding='True')">
+ <h4>Parameters:</h4>
+ <table class="paramtable">
+ <tr>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+ <xsl:apply-templates select="property" mode="parameter">
+ <xsl:sort select="count(attribute[@name='NLog.Config.RequiredParameterAttribute'])" order="descending" />
+ <xsl:sort select="@name" />
+ </xsl:apply-templates>
+ </table>
+ </xsl:if>
+ <xsl:if test="documentation/remarks">
+ <h4>Remarks:</h4>
+ <xsl:apply-templates select="documentation/remarks" />
+ </xsl:if>
+ <xsl:if test="documentation/example">
+ <h4>Example:</h4>
+ <xsl:apply-templates select="documentation/example" />
+ </xsl:if>
+ <hr size="1" />
+ <a href="layouts.html">Back to the layout list.</a>
+ </xsl:template>
+
+ <xsl:template match="property[@set='false']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@name='Name']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@name='Type']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@type='NLog.Layout']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@type='NLog.ILayout']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property" mode="parameter">
+ <xsl:call-template name="parameter_info" />
+ </xsl:template>
+
+ <xsl:template match="property[attribute/@name='NLog.Config.ArrayParameterAttribute']" mode="parameter2">
+ <xsl:variable name="itemtype" select="attribute[@name='NLog.Config.ArrayParameterAttribute']/property[@name='ElementType']/@value" />
+ <br/><<xsl:value-of select="@name" />><br/>
+ <xsl:value-of select="$itemtype" />
+ <xsl:apply-templates select="//class[@name='$itemtype']" mode="parameter" />
+ </<xsl:value-of select="@name" />>
+ </xsl:template>
+
+ <xsl:template match="property" mode="parameter2">
+ </xsl:template>
+
+ <xsl:template match="c">
+ <code><xsl:apply-templates /></code>
+ </xsl:template>
+
+ <xsl:template match="code">
+ <code><pre class="example"><xsl:apply-templates /></pre></code>
+ </xsl:template>
+
+ <xsl:template match="see">
+ <code><xsl:value-of select="@cref" /></code>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/web/links.xml b/web/links.xml
new file mode 100644
index 0000000..9ad4951
--- /dev/null
+++ b/web/links.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="links">
+ <h1>Links</h1>
+ <ol>
+ <li><a href="http://logging.apache.org/log4net/">log4net</a> library.</li>
+ <li>My <a href="http://blog.jkowalski.net/">blog</a> where I'm writing about NLog and <a href="http://www.sooda.org/">Sooda</a>.</li>
+ </ol>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
+
diff --git a/web/log4net.results.xml b/web/log4net.results.xml
new file mode 100644
index 0000000..44a0846
--- /dev/null
+++ b/web/log4net.results.xml
@@ -0,0 +1,32 @@
+<results>
+ <test logger="Non-logging" repetitions="1000000">
+ <timing name="No formatting" totalTime="00:00:00.0370000" repetitions="1000000" logsPerSecond="27119614.2161208" nanosecondsPerLog="36.8736808728484" />
+ <timing name="1 format parameter" totalTime="00:00:01.1930000" repetitions="1000000" logsPerSecond="838450.561903553" nanosecondsPerLog="1192.67616414935" />
+ <timing name="2 format parameters" totalTime="00:00:01.3510000" repetitions="1000000" logsPerSecond="740431.345739548" nanosecondsPerLog="1350.56410800814" />
+ <timing name="3 format parameters" totalTime="00:00:01.6520000" repetitions="1000000" logsPerSecond="605286.786837566" nanosecondsPerLog="1652.10941614088" />
+ <timing name="No formatting, using a guard" totalTime="00:00:00.0220000" repetitions="1000000" logsPerSecond="45286046.8352669" nanosecondsPerLog="22.0818567722993" />
+ <timing name="1 format parameter, using a guard" totalTime="00:00:00.0230000" repetitions="1000000" logsPerSecond="43360568.3621431" nanosecondsPerLog="23.0624283253877" />
+ <timing name="2 format parameters, using a guard" totalTime="00:00:00.0210000" repetitions="1000000" logsPerSecond="46642061.3720764" nanosecondsPerLog="21.4398757383969" />
+ <timing name="3 format parameters, using a guard" totalTime="00:00:00.0230000" repetitions="1000000" logsPerSecond="44109140.8714511" nanosecondsPerLog="22.6710377994969" />
+ </test>
+ <test logger="Null-appender without layout" repetitions="1000000">
+ <timing name="No formatting" totalTime="00:00:00.0280000" repetitions="1000000" logsPerSecond="36291187.6229292" nanosecondsPerLog="27.55489873713" />
+ <timing name="1 format parameter" totalTime="00:00:01.1950000" repetitions="1000000" logsPerSecond="836693.779302614" nanosecondsPerLog="1195.18039303878" />
+ <timing name="2 format parameters" totalTime="00:00:01.3570000" repetitions="1000000" logsPerSecond="736947.677063891" nanosecondsPerLog="1356.94843897758" />
+ <timing name="3 format parameters" totalTime="00:00:01.7800000" repetitions="1000000" logsPerSecond="561699.819276002" nanosecondsPerLog="1780.31034670608" />
+ <timing name="No formatting, using a guard" totalTime="00:00:00.0220000" repetitions="1000000" logsPerSecond="45353178.9270963" nanosecondsPerLog="22.049171053863" />
+ <timing name="1 format parameter, using a guard" totalTime="00:00:00.0230000" repetitions="1000000" logsPerSecond="44092840.7775123" nanosecondsPerLog="22.6794187529421" />
+ <timing name="2 format parameters, using a guard" totalTime="00:00:00.0210000" repetitions="1000000" logsPerSecond="46575910.1673303" nanosecondsPerLog="21.4703265359145" />
+ <timing name="3 format parameters, using a guard" totalTime="00:00:00.0230000" repetitions="1000000" logsPerSecond="43997455.6896679" nanosecondsPerLog="22.7285870131539" />
+ </test>
+ <test logger="Null-appender with layout rendering" repetitions="1000000">
+ <timing name="No formatting" totalTime="00:00:00.0280000" repetitions="1000000" logsPerSecond="36236814.3993845" nanosecondsPerLog="27.5962447741263" />
+ <timing name="1 format parameter" totalTime="00:00:01.2330000" repetitions="1000000" logsPerSecond="810757.767559723" nanosecondsPerLog="1233.41402329067" />
+ <timing name="2 format parameters" totalTime="00:00:01.3470000" repetitions="1000000" logsPerSecond="742320.465224502" nanosecondsPerLog="1347.12707900026" />
+ <timing name="3 format parameters" totalTime="00:00:01.7780000" repetitions="1000000" logsPerSecond="562276.239018512" nanosecondsPerLog="1778.48525441083" />
+ <timing name="No formatting, using a guard" totalTime="00:00:00.0220000" repetitions="1000000" logsPerSecond="45275163.7955023" nanosecondsPerLog="22.0871647094812" />
+ <timing name="1 format parameter, using a guard" totalTime="00:00:00.0230000" repetitions="1000000" logsPerSecond="44092840.7775123" nanosecondsPerLog="22.6794187529421" />
+ <timing name="2 format parameters, using a guard" totalTime="00:00:00.0210000" repetitions="1000000" logsPerSecond="46639022.8013029" nanosecondsPerLog="21.4412725639711" />
+ <timing name="3 format parameters, using a guard" totalTime="00:00:00.0230000" repetitions="1000000" logsPerSecond="44087410.089664" nanosecondsPerLog="22.6822124040905" />
+ </test>
+</results>
\ No newline at end of file
diff --git a/web/log4netwithformat.results.xml b/web/log4netwithformat.results.xml
new file mode 100644
index 0000000..e936fac
--- /dev/null
+++ b/web/log4netwithformat.results.xml
@@ -0,0 +1,32 @@
+<results>
+ <test logger="Non-logging" repetitions="1000000">
+ <timing name="No formatting" totalTime="00:00:00.0280000" repetitions="1000000" logsPerSecond="35363310.3475529" nanosecondsPerLog="28.277895654336" />
+ <timing name="1 format parameter" totalTime="00:00:01.2410000" repetitions="1000000" logsPerSecond="806088.362117499" nanosecondsPerLog="1240.5587861027" />
+ <timing name="2 format parameters" totalTime="00:00:01.4120000" repetitions="1000000" logsPerSecond="707985.929463375" nanosecondsPerLog="1412.45744920095" />
+ <timing name="3 format parameters" totalTime="00:00:01.8040000" repetitions="1000000" logsPerSecond="554175.359655984" nanosecondsPerLog="1804.48297199784" />
+ <timing name="No formatting, using a guard" totalTime="00:00:00.0220000" repetitions="1000000" logsPerSecond="45324465.6604538" nanosecondsPerLog="22.063139309605" />
+ <timing name="1 format parameter, using a guard" totalTime="00:00:00.0220000" repetitions="1000000" logsPerSecond="45213972.6408064" nanosecondsPerLog="22.1170567767691" />
+ <timing name="2 format parameters, using a guard" totalTime="00:00:00.0220000" repetitions="1000000" logsPerSecond="45620802.1615284" nanosecondsPerLog="21.9198250056921" />
+ <timing name="3 format parameters, using a guard" totalTime="00:00:00.0210000" repetitions="1000000" logsPerSecond="46684642.9735898" nanosecondsPerLog="21.4203201803581" />
+ </test>
+ <test logger="Null-appender without layout" repetitions="1000000">
+ <timing name="No formatting" totalTime="00:00:00.0280000" repetitions="1000000" logsPerSecond="35327013.7970511" nanosecondsPerLog="28.3069496262793" />
+ <timing name="1 format parameter" totalTime="00:00:01.3150000" repetitions="1000000" logsPerSecond="760293.893065727" nanosecondsPerLog="1315.28085273408" />
+ <timing name="2 format parameters" totalTime="00:00:01.4180000" repetitions="1000000" logsPerSecond="705229.845495629" nanosecondsPerLog="1417.97742450507" />
+ <timing name="3 format parameters" totalTime="00:00:01.7370000" repetitions="1000000" logsPerSecond="575578.755292621" nanosecondsPerLog="1737.38170633418" />
+ <timing name="No formatting, using a guard" totalTime="00:00:00.0220000" repetitions="1000000" logsPerSecond="45359500.7286321" nanosecondsPerLog="22.0460980375998" />
+ <timing name="1 format parameter, using a guard" totalTime="00:00:00.0220000" repetitions="1000000" logsPerSecond="45846931.1952457" nanosecondsPerLog="21.811710706249" />
+ <timing name="2 format parameters, using a guard" totalTime="00:00:00.0210000" repetitions="1000000" logsPerSecond="46540181.7638111" nanosecondsPerLog="21.48680907769" />
+ <timing name="3 format parameters, using a guard" totalTime="00:00:00.0210000" repetitions="1000000" logsPerSecond="46591065.8735634" nanosecondsPerLog="21.4633424080435" />
+ </test>
+ <test logger="Null-appender with layout rendering" repetitions="1000000">
+ <timing name="No formatting" totalTime="00:00:00.0280000" repetitions="1000000" logsPerSecond="35588325.9430117" nanosecondsPerLog="28.0991019808383" />
+ <timing name="1 format parameter" totalTime="00:00:01.2550000" repetitions="1000000" logsPerSecond="797113.148338008" nanosecondsPerLog="1254.5270418447" />
+ <timing name="2 format parameters" totalTime="00:00:01.4120000" repetitions="1000000" logsPerSecond="708372.623656914" nanosecondsPerLog="1411.68640148399" />
+ <timing name="3 format parameters" totalTime="00:00:01.7430000" repetitions="1000000" logsPerSecond="573827.111807913" nanosecondsPerLog="1742.68517367431" />
+ <timing name="No formatting, using a guard" totalTime="00:00:00.0220000" repetitions="1000000" logsPerSecond="45360075.5252553" nanosecondsPerLog="22.0458186724849" />
+ <timing name="1 format parameter, using a guard" totalTime="00:00:00.0210000" repetitions="1000000" logsPerSecond="46558947.4779532" nanosecondsPerLog="21.47814875913" />
+ <timing name="2 format parameters, using a guard" totalTime="00:00:00.0220000" repetitions="1000000" logsPerSecond="46474319.0257329" nanosecondsPerLog="21.5172598752076" />
+ <timing name="3 format parameters, using a guard" totalTime="00:00:00.0220000" repetitions="1000000" logsPerSecond="45980025.6904303" nanosecondsPerLog="21.7485741902951" />
+ </test>
+</results>
\ No newline at end of file
diff --git a/web/mailinglists.xml b/web/mailinglists.xml
new file mode 100644
index 0000000..26397c6
--- /dev/null
+++ b/web/mailinglists.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="mailinglists">
+ <h1>Mailing Lists</h1>
+ <p>If you're interested in NLog development, you may consider joining the following mailing lists:</p>
+ <ul>
+ <li><a href="http://lists.sourceforge.net/lists/listinfo/nlog-list">nlog-list at lists.sourceforge.net</a> - General English discussion</li>
+ <li><a href="http://lists.sourceforge.net/lists/listinfo/nlog-commits">nlog-commits at lists.sourceforge.net</a> - SVN commits</li>
+ </ul>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
+
diff --git a/web/menubullet.png b/web/menubullet.png
new file mode 100644
index 0000000..dd60e97
Binary files /dev/null and b/web/menubullet.png differ
diff --git a/web/netapi.xml b/web/netapi.xml
new file mode 100644
index 0000000..4030080
--- /dev/null
+++ b/web/netapi.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" subid="netapi">
+ <h1>.NET API</h1>
+ <p>
+ NLog uses a simple logging API which is similar to the one provided by <a href="http://logging.apache.org/log4net">log4net</a>.
+ There are 2 classes that you interact with: <code>LogManager</code> and <code>Logger</code>.
+ Note that <code>Logger</code> a concrete class not an interface (like ILog from log4net).
+ </p>
+ <h5>Log Manager</h5>
+ <p>
+ LogManager contains methods and properties to create loggers and manage logging configuration.
+ Click on each method to see the API documentation:
+ </p>
+ <ul>
+ <li><a href="help/NLog.LogManager.GetLogger.html">LogManager.GetLogger</a> - gets or creates the specified logger</li>
+ <li><a href="help/NLog.LogManager.GetCurrentClassLogger.html">LogManager.GetCurrentClassLogger</a> - gets or creates the logger for currently executing class</li>
+ <li><a href="help/NLog.LogManager.Configuration.html">LogManager.Configuration</a> - gets or sets the current logging configuration information</li>
+ <li><a href="help/NLog.LogManager.GlobalThreshold.html">LogManager.GlobalThreshold</a> - gets or sets the global logging threshold</li>
+ </ul>
+ <p>Full list of members of the LogManager class can be found <a href="help/NLog.LogManagerMembers.html">here</a>.</p>
+ <p>
+ It's recommended to use <a href="help/NLog.LogManager.GetLogger.html">LogManager.GetLogger("loggerName")</a>
+ to create a logger for each class, store it in a static field and use for logging. We recommend having a consistently-named
+ variable that holds logger instance for each class. <code>logger</code> might not be a bad option for the logger
+ name.
+ </p>
+ <p>
+ The following example shows the code that uses the recommended way of creating and keeping logger instance.
+ </p>
+ <code lang="C#" src="examples/web/GetLogger.cs" />
+ <p>
+ It's also possible to use or
+ <a href="help/NLog.LogManager.GetCurrentClassLogger.html">LogManager.GetCurrentClassLogger()</a>
+ but this feature isn't supported in Compact Framework configuration, so if you want
+ to support mobile devices you shouldn't use this syntax. GetCurrentClassLogger is also quite
+ costly because internally it uses the <code>StackTrace</code> class to get the name of the
+ current class.
+ </p>
+ <code lang="C#" src="examples/web/GetCurrentClassLogger.cs" />
+ <h5>Logger</h5>
+ <p>
+ The <a href="help/NLog.Logger.html">NLog.Logger</a> class has the following methods. Each method has a number
+ of overloads designed to minimize the number of memory allocations in order to improve logging speed.
+ Click on a method name to see the list of overloads for it.
+ </p>
+ <ul>
+ <li><a href="help/NLog.Logger.Log_overloads.html">Log()</a> - Writes the diagnostic message at the specified level using the specified format provider and format parameters. </li>
+ <li><a href="help/NLog.Logger.Trace_overloads.html">Trace()</a> - Writes the diagnostic message at the Trace level using the specified format provider and format parameters. </li>
+ <li><a href="help/NLog.Logger.Debug_overloads.html">Debug()</a> - Writes the diagnostic message at the Debug level using the specified format provider and format parameters. </li>
+ <li><a href="help/NLog.Logger.Info_overloads.html">Info()</a> - Writes the diagnostic message at the Info level using the specified format provider and format parameters. </li>
+ <li><a href="help/NLog.Logger.Warn_overloads.html">Warn()</a> - Writes the diagnostic message at the Warn level using the specified format provider and format parameters. </li>
+ <li><a href="help/NLog.Logger.Error_overloads.html">Error()</a> - Writes the diagnostic message at the Error level using the specified format provider and format parameters. </li>
+ <li><a href="help/NLog.Logger.Fatal_overloads.html">Fatal()</a> - Writes the diagnostic message at the Fatal level using the specified format provider and format parameters. </li>
+ </ul>
+ <p>
+ The following methods and properties let you determine whether logging is enabled for the specified level:
+ </p>
+ <ul>
+ <li><a href="help/NLog.Logger.IsEnabled.html">IsEnabled()</a> - Determines if logging is enabled for the specified level.</li>
+ <li><a href="help/NLog.Logger.IsTraceEnabled.html">IsTraceEnabled</a> - Determines if logging is enabled for the Trace level.</li>
+ <li><a href="help/NLog.Logger.IsDebugEnabled.html">IsDebugEnabled</a> - Determines if logging is enabled for the Debug level.</li>
+ <li><a href="help/NLog.Logger.IsInfoEnabled.html">IsInfoEnabled</a> - Determines if logging is enabled for the Info level.</li>
+ <li><a href="help/NLog.Logger.IsWarnEnabled.html">IsWarnEnabled</a> - Determines if logging is enabled for the Warn level.</li>
+ <li><a href="help/NLog.Logger.IsErrorEnabled.html">IsErrorEnabled</a> - Determines if logging is enabled for the Error level.</li>
+ <li><a href="help/NLog.Logger.IsFatalEnabled.html">IsFatalEnabled</a> - Determines if logging is enabled for the Fatal level.</li>
+ </ul>
+ <p>Full list of members of the Logger class can be found <a href="help/NLog.LoggerMembers.html">here</a>.</p>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
+
diff --git a/web/news.xml b/web/news.xml
new file mode 100644
index 0000000..0ef7431
--- /dev/null
+++ b/web/news.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="news">
+ <h1>News</h1>
+ <table width="100%">
+ <tr><td class="newsdate">TBA</td><td class="newstext">
+ <p><b style="color: red">NLog 0.95 has been released!</b>. Click <link href="releasenotes">here</link> for the release notes. Source and binary packages can be found <link href="download">here</link>.</p>
+ </td>
+ </tr>
+ <tr><td class="newsdate">2005-06-09</td><td class="newstext">
+ <p>NLog 0.9 has been released!. Click <link href="releasenotes">here</link> for the release notes. Source and binary packages can be found <link href="download">here</link>.</p>
+ </td>
+ </tr>
+ <tr><td class="newsdate">2005-03-08</td><td class="newstext">NLog 0.5 beta 1 has been released!. This work is based on 6 months of testing and should be production-ready. Download it <a href="http://sourceforge.net/project/showfiles.php?group_id=116456">here</a>.</td></tr>
+ </table>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/nlog.results.xml b/web/nlog.results.xml
new file mode 100644
index 0000000..4b99ac5
--- /dev/null
+++ b/web/nlog.results.xml
@@ -0,0 +1,32 @@
+<results>
+ <test logger="Non-logging" repetitions="1000000">
+ <timing name="No formatting" totalTime="00:00:00.0080000" repetitions="1000000" logsPerSecond="132232914.665682" nanosecondsPerLog="7.5624136587192" />
+ <timing name="1 format parameter" totalTime="00:00:00.0080000" repetitions="1000000" logsPerSecond="122143758.95721" nanosecondsPerLog="8.18707405550147" />
+ <timing name="2 format parameters" totalTime="00:00:00.0280000" repetitions="1000000" logsPerSecond="36267654.86636" nanosecondsPerLog="27.5727781044798" />
+ <timing name="3 format parameters" totalTime="00:00:00.0350000" repetitions="1000000" logsPerSecond="28821741.4409482" nanosecondsPerLog="34.6960298026705" />
+ <timing name="No formatting, using a guard" totalTime="00:00:00.0070000" repetitions="1000000" logsPerSecond="144324852.834449" nanosecondsPerLog="6.92881357826204" />
+ <timing name="1 format parameter, using a guard" totalTime="00:00:00.0070000" repetitions="1000000" logsPerSecond="142356134.420362" nanosecondsPerLog="7.02463581265217" />
+ <timing name="2 format parameters, using a guard" totalTime="00:00:00.0070000" repetitions="1000000" logsPerSecond="144330672.150317" nanosecondsPerLog="6.9285342131472" />
+ <timing name="3 format parameters, using a guard" totalTime="00:00:00.0070000" repetitions="1000000" logsPerSecond="144330672.150317" nanosecondsPerLog="6.9285342131472" />
+ </test>
+ <test logger="Null-appender without layout" repetitions="1000000">
+ <timing name="No formatting" totalTime="00:00:00.1590000" repetitions="1000000" logsPerSecond="6294225.63271163" nanosecondsPerLog="158.875778904861" />
+ <timing name="1 format parameter" totalTime="00:00:00.2010000" repetitions="1000000" logsPerSecond="4979820.81495806" nanosecondsPerLog="200.810438198151" />
+ <timing name="2 format parameters" totalTime="00:00:00.2130000" repetitions="1000000" logsPerSecond="4705061.60733768" nanosecondsPerLog="212.537068258675" />
+ <timing name="3 format parameters" totalTime="00:00:00.2330000" repetitions="1000000" logsPerSecond="4289027.32146152" nanosecondsPerLog="233.153096273409" />
+ <timing name="No formatting, using a guard" totalTime="00:00:00.1610000" repetitions="1000000" logsPerSecond="6212880.69579223" nanosecondsPerLog="160.95593154996" />
+ <timing name="1 format parameter, using a guard" totalTime="00:00:00.2060000" repetitions="1000000" logsPerSecond="4862574.06859003" nanosecondsPerLog="205.652394368558" />
+ <timing name="2 format parameters, using a guard" totalTime="00:00:00.2180000" repetitions="1000000" logsPerSecond="4588807.27123555" nanosecondsPerLog="217.921551482102" />
+ <timing name="3 format parameters, using a guard" totalTime="00:00:00.2370000" repetitions="1000000" logsPerSecond="4223886.16241845" nanosecondsPerLog="236.748804666515" />
+ </test>
+ <test logger="Null-appender with layout rendering" repetitions="1000000">
+ <timing name="No formatting" totalTime="00:00:02.7100000" repetitions="1000000" logsPerSecond="369043.367488961" nanosecondsPerLog="2709.70863615348" />
+ <timing name="1 format parameter" totalTime="00:00:03.7000000" repetitions="1000000" logsPerSecond="270289.688459089" nanosecondsPerLog="3699.73418409323" />
+ <timing name="2 format parameters" totalTime="00:00:03.8000000" repetitions="1000000" logsPerSecond="263152.516487902" nanosecondsPerLog="3800.07766350193" />
+ <timing name="3 format parameters" totalTime="00:00:04.0620000" repetitions="1000000" logsPerSecond="246186.326352651" nanosecondsPerLog="4061.96402056686" />
+ <timing name="No formatting, using a guard" totalTime="00:00:02.6320000" repetitions="1000000" logsPerSecond="379986.618100044" nanosecondsPerLog="2631.67162306941" />
+ <timing name="1 format parameter, using a guard" totalTime="00:00:03.4930000" repetitions="1000000" logsPerSecond="286322.163456505" nanosecondsPerLog="3492.56930699293" />
+ <timing name="2 format parameters, using a guard" totalTime="00:00:03.6730000" repetitions="1000000" logsPerSecond="272257.378903654" nanosecondsPerLog="3672.99503149143" />
+ <timing name="3 format parameters, using a guard" totalTime="00:00:04.0670000" repetitions="1000000" logsPerSecond="245881.747169287" nanosecondsPerLog="4066.99566565024" />
+ </test>
+</results>
\ No newline at end of file
diff --git a/web/nlog_routing.png b/web/nlog_routing.png
new file mode 100644
index 0000000..e1984fb
Binary files /dev/null and b/web/nlog_routing.png differ
diff --git a/web/out_link.gif b/web/out_link.gif
new file mode 100644
index 0000000..e948720
Binary files /dev/null and b/web/out_link.gif differ
diff --git a/web/performance.xml b/web/performance.xml
new file mode 100644
index 0000000..461304d
--- /dev/null
+++ b/web/performance.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation">
+ <h2>Performance</h2>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/plain.menu b/web/plain.menu
new file mode 100644
index 0000000..846b317
--- /dev/null
+++ b/web/plain.menu
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<common>
+</common>
diff --git a/web/prettyprint.xsl b/web/prettyprint.xsl
new file mode 100644
index 0000000..e94bb34
--- /dev/null
+++ b/web/prettyprint.xsl
@@ -0,0 +1,224 @@
+<?xml version="1.0"?>
+<!--
+IE5 default style sheet, provides a view of any XML document
+and provides the following features:
+- auto-indenting of the display, expanding of entity references
+- click or tab/return to expand/collapse
+- color coding of markup
+- color coding of recognized namespaces - xml, xmlns, xsl
+
+This style sheet is available in IE5 in a compact form at the URL
+"res://msxml.dll/DEFAULTSS.xsl". This version differs only in the
+addition of comments and whitespace for readability.
+
+Author: Jonathan Marsh (jmarsh at microsoft.com)
+Modified: 05/21/2001 by Nate Austin (naustin at idsgrp.com)
+Converted to use XSLT rather than WD-xsl
+-->
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <!-- Templates for each node type follows. The output of
+ each template has a similar structure to enable script to
+ walk the result tree easily for handling user
+ interaction. -->
+
+ <!-- Template for the DOCTYPE declaration. No way to get
+ the DOCTYPE, so we just put in a placeholder -->
+
+ <!-- no support for doctypes
+ <xsl:template match="node()[nodeType()=10]">
+ <DIV class="e"><SPAN>
+ <SPAN class="b"> </SPAN>
+ <SPAN class="d"><!DOCTYPE <xsl:value-of
+ select="name()"/><I> (View
+ Source for full doctype...)</I>></SPAN>
+ </SPAN></DIV>
+ </xsl:template>
+ -->
+
+ <!-- Template for pis not handled elsewhere -->
+ <xsl:template match="processing-instruction()">
+ <DIV class="e">
+ <SPAN class="b"> </SPAN>
+ <SPAN class="m"><?</SPAN><SPAN class="pi"><xsl:value-of
+ select="name()"/> <xsl:value-of select="."/></SPAN><SPAN
+ class="m">?></SPAN>
+ </DIV>
+ </xsl:template>
+
+ <!-- Template for the XML declaration. Need a separate template because the
+ pseudo-attributes
+ are actually exposed as attributes instead of just element content, as
+ in other pis -->
+ <!-- No support for the xml declaration
+ <xsl:template match="pi('xml')">
+ <DIV class="e">
+ <SPAN class="b"> </SPAN>
+ <SPAN class="m"><?</SPAN><SPAN class="pi">xml
+ <xsl:for-each
+ select="@*"><xsl:value-of select="name()"/>="<xsl:value-of select="."/>"
+ </xsl:for-each></SPAN><SPAN class="m">?></SPAN>
+ </DIV>
+ </xsl:template>
+ -->
+
+ <!-- Template for attributes not handled elsewhere -->
+ <xsl:template match="@*" xml:space="preserve"><SPAN><xsl:attribute
+ name="class"><xsl:if
+ test="starts-with(name(),'xsl:')">x</xsl:if>t</xsl:attribute>
+ <xsl:value-of
+ select="name()" /></SPAN><SPAN class="m">="</SPAN>
+ <B><xsl:value-of
+ select="."/></B><SPAN class="m">"</SPAN></xsl:template>
+
+ <!-- Template for attributes in the xmlns or xml namespace -->
+ <!-- UNKNOWN
+ <xsl:template match="@xmlns:*|@xmlns|@xml:*"><SPAN
+ class="ns"> <xsl:value-of
+ select="name()"/></SPAN><SPAN class="m">="</SPAN>
+ <B class="ns"><xsl:value-of
+ select="."/></B><SPAN class="m">"</SPAN></xsl:template>
+ -->
+
+ <!-- Template for text nodes -->
+ <xsl:template match="text()">
+ <DIV class="e">
+ <SPAN class="b"> </SPAN>
+ <SPAN class="tx"><xsl:value-of select="."/></SPAN>
+ </DIV>
+ </xsl:template>
+
+
+ <!-- Note that in the following templates for comments
+ and cdata, by default we apply a style appropriate for
+ single line content (e.g. non-expandable, single line
+ display). But we also inject the attribute 'id="clean"' and
+ a script call 'f(clean)'. As the output is read by the
+ browser, it executes the function immediately. The function
+ checks to see if the comment or cdata has multi-line data,
+ in which case it changes the style to a expandable,
+ multi-line display. Performing this switch in the DHTML
+ instead of from script in the XSL increases the performance
+ of the style sheet, especially in the browser's asynchronous
+ case -->
+
+ <!-- Template for comment nodes -->
+ <xsl:template match="comment()">
+ <DIV class="k">
+ <SPAN><A class="b" onclick="return false" onfocus="h()"
+ STYLE="visibility:hidden">-</A> <SPAN class="m">
+ <!--</SPAN></SPAN>
+ <SPAN id="clean" class="ci"><PRE>
+ <xsl:value-of select="."/></PRE></SPAN>
+ <SPAN class="b"> </SPAN> <SPAN
+ class="m">--></SPAN>
+ </DIV>
+ </xsl:template>
+
+ <!-- UNSUPPORTED
+ <xsl:template match="cdata()">
+ <DIV class="k">
+ <SPAN><A class="b" onclick="return false" onfocus="h()"
+ STYLE="visibility:hidden">-</A> <SPAN class="m">
+ <![CDATA[</SPAN></SPAN>
+ <SPAN id="clean" class="di"><PRE><xsl:value-of
+ select="."/></PRE></SPAN>
+ <SPAN class="b"> </SPAN> <SPAN
+ class="m">]]></SPAN>
+ <SCRIPT>f(clean);</SCRIPT></DIV>
+ </xsl:template>
+ -->
+
+
+ <!-- Note the following templates for elements may
+ examine children. This harms to some extent the ability to
+ process a document asynchronously - we can't process an
+ element until we have read and examined at least some of its
+ children. Specifically, the first element child must be
+ read before any template can be chosen. And any element
+ that does not have element children must be read completely
+ before the correct template can be chosen. This seems an
+ acceptable performance loss in the light of the formatting
+ possibilities available when examining children. -->
+
+ <!-- Template for elements not handled elsewhere (leaf nodes) -->
+ <xsl:template match="*">
+ <DIV class="e"><DIV STYLE="margin-left:1em;text-indent:-2em">
+ <SPAN class="b"> </SPAN>
+ <SPAN class="m"><</SPAN><SPAN><xsl:attribute
+ name="class"><xsl:if
+ test="starts-with(name(),'xsl:')">x</xsl:if>t</xsl:attribute>
+ <xsl:value-of
+ select="name()"/></SPAN> <xsl:apply-templates
+ select="@*"/><SPAN class="m">
+ /></SPAN>
+ </DIV></DIV>
+ </xsl:template>
+
+ <!-- Template for elements with comment, pi and/or cdata children -->
+ <xsl:template match="*[comment() | processing-instruction()]">
+ <DIV class="e">
+ <DIV class="c"><A href="#" onclick="return false" onfocus="h()"
+ class="b">-</A> <SPAN
+ class="m"><</SPAN><SPAN><xsl:attribute
+ name="class"><xsl:if
+ test="starts-with(name(),'xsl:')">x</xsl:if>t</xsl:attribute>
+ <xsl:value-of
+ select="name()"/></SPAN><xsl:apply-templates select="@*"/>
+ <SPAN
+ class="m">></SPAN></DIV>
+ <DIV><xsl:apply-templates/>
+ <DIV><SPAN class="b"> </SPAN> <SPAN
+ class="m"></</SPAN><SPAN><xsl:attribute name="class">
+ <xsl:if
+ test="starts-with(name(),'xsl:')">x</xsl:if>t</xsl:attribute>
+ <xsl:value-of
+ select="name()"/></SPAN><SPAN class="m">></SPAN></DIV>
+ </DIV></DIV>
+ </xsl:template>
+
+ <!-- Template for elements with only text children -->
+ <xsl:template match="*[text() and not(comment() |
+ processing-instruction())]">
+ <DIV class="e"><DIV STYLE="margin-left:1em;text-indent:-2em">
+ <SPAN class="b"> </SPAN> <SPAN
+ class="m"><</SPAN><SPAN><xsl:attribute
+ name="class"><xsl:if
+ test="starts-with(name(),'xsl:')">x</xsl:if>t</xsl:attribute>
+ <xsl:value-of
+ select="name()"/></SPAN><xsl:apply-templates select="@*"/>
+ <SPAN class="m">></SPAN><SPAN class="tx">
+ <xsl:value-of
+ select="."/></SPAN><SPAN class="m"></</SPAN>
+ <SPAN><xsl:attribute
+ name="class"><xsl:if
+ test="starts-with(name(),'xsl:')">x</xsl:if>t</xsl:attribute>
+ <xsl:value-of
+ select="name()"/></SPAN><SPAN class="m">></SPAN>
+ </DIV></DIV>
+ </xsl:template>
+
+ <!-- Template for elements with element children -->
+ <xsl:template match="*[*]">
+ <DIV class="e">
+ <DIV class="c" STYLE="margin-left:1em;text-indent:-2em"><A href="#"
+ onclick="return false" onfocus="h()" class="b">-</A> <SPAN
+ class="m"><</SPAN><SPAN>
+ <xsl:attribute name="class"><xsl:if
+ test="starts-with(name(),'xsl:')">x</xsl:if>t</xsl:attribute>
+ <xsl:value-of
+ select="name()"/></SPAN><xsl:apply-templates select="@*"/> <SPAN
+ class="m">></SPAN></DIV>
+ <DIV><xsl:apply-templates/>
+ <DIV><SPAN class="b"> </SPAN> <SPAN
+ class="m"></</SPAN><SPAN><xsl:attribute
+ name="class"><xsl:if
+ test="starts-with(name(),'xsl:')">x</xsl:if>
+ t</xsl:attribute><xsl:value-of
+ select="name()"/></SPAN><SPAN class="m">></SPAN></DIV>
+ </DIV></DIV>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/web/releasenotes.xml b/web/releasenotes.xml
new file mode 100644
index 0000000..c58d2e0
--- /dev/null
+++ b/web/releasenotes.xml
@@ -0,0 +1,415 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="releasenotes">
+ <h1>Release Notes</h1>
+ <table width="100%">
+ <tr class="releasenote">
+ <td class="newsdate">2006-09-18</td>
+ <td class="newstext">
+ <b style="font-size: 150%; color: red">NLog 1.0 has been released.!</b>
+ <p>
+ After 2 years of work, we're proud to announce the availability of NLog 1.0. NLog is a logging library designed
+ with simplicity and flexibility in mind. See <a href="http://www.nlog-project.org">http://www.nlog-project.org</a> for more
+ information about NLog.
+ </p>
+ <p>
+ Source, binary packages and installer packages are available for
+ download from: <a href="http://www.nlog-project.org/download.html">http://www.nlog-project.org/download.html</a>
+ </p>
+ <p>
+ Tutorial and reference documentation are available at:
+ <a href="http://www.nlog-project.org/documentation.html">http://www.nlog-project.org/documentation.html</a>
+ </p>
+ <p>
+ The following people have contributed to NLog by submitting code or bug reports:
+ </p>
+ <ul>
+ <li>Jaroslaw Kowalski <code><jaak at jkowalski dot net></code></li>
+ <li>Marcin Krupinski <code><yoszek at gmail dot com></code></li>
+ <li>Inez Korczynski <code><korczynski at gmail dot com></code></li>
+ <li>Rafal Gwizdala <code><gwrafal at poczta dot onet dot pl></code></li>
+ <li>Yuri Mamrukov <code><yvm at att dot net></code></li>
+ <li>Maciej Figatowski <code><mfigatow at sav dot net></code></li>
+ <li>Perry Rapp <code><lifelines_3_0_18 at hotmail dot com></code></li>
+ <li>Maarten Claes <code><m.claes at farcourier dot com></code></li>
+ </ul>
+ <p>
+ The focus of this relase is future compatibility. Code has been added to ensure
+ that the development of NLog will progress without breaking existing code.
+ The following paragraphs describe changes that made after 1.0 RC1 release.
+ </p>
+ <p>
+ Breaking API changes:
+ </p>
+ <ul>
+ <li>Added NLog.ILayout which Layout implements to allow other layout types
+ (such as CSV-escaped, HTML-colored, XML-escaped, ANSI-colored) to be implemented.</li>
+ <li>NLog.Layout became sealed.</li>
+ <li>FileTarget.KeepFileOpen is back to the default
+ of false. we now have <x><default-target-parameters /></x> so this default can be easily overriden.</li>
+ <li>Added NLog.TargetWithLayout, removed Layout and CompiledLayout from NLog.Target</li>
+ <li>Removed CSVFile target, converted examples to File + CsvLayout</li>
+ <li>Removed LogEventInfo.Empty and replaced with LogEventInfo.CreateNullEvent()</li>
+ <li>Changed the default value of FileTarget.OpenFileCacheTimeout to -1</li>
+ </ul>
+ <p>
+ Packaging changes:
+ </p>
+ <ul>
+ <li>Added publisher policy generation and established NLog versioning policy. See <a href="http://blog.jkowalski.net/?p=55">http://blog.jkowalski.net/?p=55</a>
+ for more information about NLog versioning policy.</li>
+ <li>Build number is synchronized with SVN number.</li>
+ <li>Added VJSharp and Web item templates. Updated the installer to support VWD Express 2005.</li>
+ <li>Synchronized Visual Studio solutions to source code directories. Now part of the build process.</li>
+ <li>New NLog.Benchmark that uses code generation and compilation to create more "clean" environment.</li>
+ </ul>
+ <p>
+ Changes to the logging infrastructure:
+ </p>
+ <ul>
+ <li>Added <x><targets><default-target-parametes /> </targets></x> that specifies default values for all targets in the section</li>
+ <li>Added Initialize() and Close() to the LayoutRender class</li>
+ <li>Added optimized CurrentTimeGetter which is way faster than DateTime.Now</li>
+ <li>Fixed LayoutRenderer.ApplyPadding() null handling</li>
+ <li>Added infrastructure to create your own logger types inheriting from Logger:
+
+ <code lang="C#">
+ LogManager.GetLogger(string name, Type type)
+ LogManager.GetCurrentClassLogger(Type type)
+ LogFactory.GetLogger(string name, Type type)
+ LogFactory.GetCurrentClassLogger(Type type)
+ </code>
+ </li>
+ <li>Added PopulateLayouts() method to ILayout</li>
+ <li>Added ${event-context} layout renderer that extracts information from LogEventInfo.Context</li>
+ <li>Added LogManager<LoggerType> that manages logger instances of LoggerType where LoggerType : Logger</li>
+ <li>Added support for nested layout renderers. Used in ${file-contents}:
+ <code lang="C#">
+ ${file-contents:fileName=${basedir}/aaa.txt}
+ </code>
+ </li>
+ <li>Added support for DEFAULT nested layout parameters. You can now write:
+ <code lang="C#">
+ ${file-contents:${basedir}/file.txt}
+ ${rot13:URYYB}
+ </code>
+ </li>
+ <li>Added pluggable layouts (CSV, Log4JXml), LayoutFactory and LayoutAttribute. The syntax is:
+ <code lang="XML">
+ <![CDATA[
+ <target xsi:type="File">
+ <layout xsi:type="CSVLayout">
+ <column name="message" layout="${message}" />
+ <column name="level" layout="${level}" />
+ </layout>
+ </target>
+ ]]>
+ </code>
+ <p>
+ Of course the old syntax is still supported for simple layouts:
+ </p>
+
+ <code lang="XML">
+ <![CDATA[
+ <target xsi:type="File" layout="${message}" />
+ ]]>
+ </code>
+ </li>
+ <li>Added ILayoutWithHeaderAndFooter for layouts that support header/footer (such as CSV Layout, more to come)</li>
+ <li>Enhanced XSD Schema generation by properly generating abstract and layout properties.</li>
+ <li>Added FilterResult.IgnoreFinal and FilterResult.LogFinala which suppress processing of further rules
+ if the filter matches.</li>
+ <li>Added NLogConfigurationException which is thrown instead of CLR exceptions when the configuration fails</li>
+ <li>Simplified XmlLoggingConfiguration by splitting large methods and moving common functionality to PropertyHelper</li>
+ <li>Added [DefaultParameter] attribute which allows for nameless parameters to layout renderers:
+ <code lang="NLog Layout Renderer">
+ ${aspnet-application}
+ ${aspnet-request}
+ ${aspnet-session}
+ ${date}
+ ${environment}
+ ${file-contents}
+ ${gdc}
+ ${mdc}
+ ${process-info}
+ ${special-folder}
+ ${asp-application}
+ ${asp-request}
+ ${asp-session}
+ </code>
+ </li>
+ <li>Moved the implementation of LogManager to a reusable LogFactory while maintaining its public interface.
+ You can now easily have a private LogManager for an assembly.</li>
+ </ul>
+ <p>
+ New additions:
+ </p>
+ <ul>
+ <li>Added MaxMessageSize (default: 65000) and OnOverflow (default:Split) to
+ the Network target</li>
+ <li>Implemented headers and footers for the File target.
+ <b>CAUTION</b> NLog automatically writes footers for files that have not been
+ written for 2 days (48 hours). This is done do conserve memory for
+ long-running processes that create lots of log files.</li>
+ <li>Enabled DatabaseTarget.ConnectionString to include layouts.</li>
+ <li>Added eventID and categoryID parameters to EventLog targets.</li>
+ <li>Added ${file-contents} layout renderer which inserts file contents.</li>
+ <li>Added MailTarget.AddNewLines to insert new lines between header/lines/footer</li>
+ <li>Added FormControl target that logs to Text property of any Windows.Forms.Control</li>
+ <li>Added RichTextBox target with row- and word coloring that logs to RichTextBox</li>
+ <li>Added ${tempdir} and ${specialfolder}</li>
+ <li>Added ${gc} which can be used to get the GC statistics (very limited)</li>
+ <li>Added ${processinfo} which can be used to extract the performance information about the current process (possibly others in the future as well)</li>
+ <li>Added ImpersonatingWrapper which temporarily changes the credentials for the duration of the write.</li>
+ <li>Added NLog_Init() and NLog_InitLocal() APIs to NLogC</li>
+ </ul>
+ <p>
+ Bug fixes:
+ </p>
+ <ul>
+ <li>Fixed File target for Windows 98</li>
+ <li>Fixed Network target to work properly with IPV6</li>
+ <li>Changed RichTextBox Target to be thread safe. Uses delegate to log to RichTextBox</li>
+ </ul>
+ <p>
+ Documentation updates:
+ </p>
+ <ul>
+ <li>Added examples of inheriting from Logger class and wrapping it</li>
+ <li>Added missing code documentation</li>
+ <li>Added example ${rot13} layout renderer - that demonstrates how wrapper layout renderers can be written.</li>
+ <li>Added proper camelCasing to the web build process</li>
+ <li>Fix for multiple email addresses being passed in To,CC and BCC fields under .NET 2.0 (reported by Pawel Parzychowski)</li>
+ </ul>
+ </td>
+ </tr>
+ <tr class="releasenote">
+ <td class="newsdate">2006-06-27</td>
+ <td class="newstext">
+ <p><b>NLog 1.0 Release Candidate 1 is available!</b></p>
+ <p>
+ After 2 years of work, we're proud to announce the availability of NLog 1.0 Release Candidate 1.
+ </p>
+ <p>
+ Packaging changes:
+ </p>
+ <ul>
+ <li>Separate compilation of NLog for all supported frameworks. Starting with NLog v1.0 there will be releases
+ for each supported platform (currently 7!), both debug and release.
+ </li>
+ <li>Merged NLog.Win32.dll, NLog.DotNet.dll, NLog.Unix.dll and NLog.Mono.dll into one assembly NLog.dll</li>
+ <li>Added generation of NLog.xsd schema for Visual Studio Intellisense.</li>
+ <li>Prepared ready-to-run example projects for VS2005 that describe most targets.</li>
+ <li>Compilation, schema generation a and website building are supported on Linux/Mono. All unit tests pass.</li>
+ <li>Added support for VC#Express and VBExpress to the installer.</li>
+ <li>Added VS2005 C# and VB.NET code snippet (nlogger) to quickly insert logger creation statement</li>
+ <li>Added VS2005 item templates for NLog configuration. NLog now looks for "NLog.config" in addition to other config file names.</li>
+ </ul>
+ <p>
+ Changes to the logging infrastructure:
+ </p>
+ <ul>
+ <li>BREAKING CHANGE - Completely restructured the way File target works.
+ The new structure is based on Streams instead of StreamWriters and enables
+ archiving (kind of similar to "rolling file appender" from log4net world,
+ but supporting multiple files at a time!). It also speeds up things a lot.</li>
+ <li>Refactored file watching - should speed up non-logging by 100%</li>
+ <li>BREAKING CHANGE - removed some properties which accepted strings. Replaced with enums for type safety.</li>
+ <li>
+ Added attributes which mark support for particular runtimes and OSes.
+ They are used for generating documentation and disabling particular targets/layout renderers at runtime.
+ </li>
+ <li>Optimization to defer calling String.Format() until it's really needed.</li>
+ <li>Added LayoutRenderer.IsAppDomainFixed() and an optimization to turn such
+ things into literals. So if you use "${basedir}/log.txt" this gets converted
+ into a literal which takes no time to recalculate.</li>
+ <li>Added LoggingConfiguration.GetConfiguredNamedTargets() API</li>
+ <li>Added Layout.Escape() which escapes ${ with ${literal:text=${}</li>
+ <li>Added Logger.Log(LogEventInfo) overload</li>
+ <li>Added Logger.Log(Type,LogEventInfo) overload - useful for wrapping NLog.Logger</li>
+ <li>Added LoggerReconfiguredDelegate and Logger.LoggerReconfigured events</li>
+ <li>
+ Added InternalLogger.LogToConsoleError and their config file and
+ environment variable counterparts to send log output to Console.Error.
+ </li>
+ <li>Added support for flags-type enumerations.</li>
+ <li>Added <include file="..." ignoreErrors="true|false" /></li>
+ <li>Fixed autoReload to keep monitoring the file if the reloaded file has an error</li>
+ <li>Added <x><default-wrapper /></x> that wraps all targets in <x><targets /></x> section with the specified wrapper. The usage is:
+ <code lang="XML">
+ <![CDATA[
+ <targets>
+ <default-wrapper type="AsyncWrapper" />
+ <target name="f" type="File" />
+ <target name="n" type="Network" />
+ </targets>
+ ]]>
+ </code>
+
+ This creates "f" which is actually a AsyncWrapper(File) and "n" which is
+ AsyncWrapper(Network). Note that the original target names are renamed as
+ "f_wrapped" and "n_wrapped" respectively.
+ </li>
+ </ul>
+ <p>
+ New additions:
+ </p>
+ <ul>
+ <li>Implemented AsyncWrapper for .NET CF using the Timer class</li>
+ <li>Added WebService target supporting SOAP 1.1, SOAP 1.2, HTTP GET and HTTP POST web service calls.</li>
+ <li>Added CSVFile target which does proper CSV (comma-separated values) formatting (multi-line and
+ special character quoting). This enables you to analyze your log files in MS
+ Excel.</li>
+ <li>Added caching to File target to optimize the number file open/close operations.</li>
+ <li>
+ Added an option for multiple processes to append to the same OPEN file in a synchronized manner.
+ Unixes get this for free, but Win32 requires you to use mutexes to synchronize file access.
+ This gives a nice performance boost.
+ </li>
+ <li>Added deleteOldFileOnStartup to the File target</li>
+ <li>Added replaceFileContentsOnEachWrite to the File target</li>
+ <li>Added FileTarget.LineEnding</li>
+ </ul>
+ </td>
+ </tr>
+ <tr class="altreleasenote">
+ <td class="newsdate">2006-02-20</td>
+ <td class="newstext">
+ <p><b style="color: red; font-size: 16px">NLog 0.95 has been released!</b></p>
+ <p>
+ Major changes:
+ </p>
+ <ul>
+ <li>Added new Trace level, more verbose than the Debug level.</li>
+ <li>Added a new <a href="http://www.nlog-project.org/conditions.html">conditions language</a> which
+ lets you write powerful filtering conditions while keeping the syntax natural and readable</li>
+ <li><b><u>BREAKING CHANGE</u></b>: Renamed <code>Target.Append()</code> method to <code>Target.Write()</code></li>
+ <li>Added <code>Target.Write(LogEvent[] manyEvents)</code> for cases where the
+ target can optimize group writes</li>
+ <li>Added global log threshold and configurability at the config level (<x><nlog globalThreshold="..." /></x>)</li>
+ <li>Added support for <x><variable name="" value="" /></x> configuration element. Details are <a href="http://sourceforge.net/mailarchive/message.php?msg_id=12189220">here</a>.</li>
+ <li>Added infrastructure for <a href="http://sourceforge.net/mailarchive/message.php?msg_id=13149726">compound targets and wrapper targets</a>.</li>
+ <li>Added detailed documentation with examples for many targets, both on the website and in the help file</li>
+ </ul>
+ <p>
+ Bugs fixed:
+ </p>
+ <ul>
+ <li>Fixed the filter configuration bug as reported by Ron Grabowski</li>
+ <li>
+ Fixed a serious reentrancy bug which caused all sorts of problems
+ when formatted message included a parameter where ToString
+ did the logging itself. More details <a href="http://trac.nlog-project.org/nlog/ticket/64">here</a>.
+ </li>
+ <li>Fixed a nullref exception when no config file was present.</li>
+ <li>Fixed support for CC field in the Mail target</li>
+ <li>Fixed Close() behaviour for unnamed targets (like the ones configured by SimpleConfigurator)</li>
+ <li>Typos in the code prevented Chainsaw target from working properly.</li>
+ <li>${callsite} not working with database parameters</li>
+ <li>${callsite} doesn't work with MethodCall target and NLogViewer target</li>
+ <li>Connection string builder omits ; after Server parameter</li>
+ <li>Fixed the Trace target in Release mode by defining TRACE symbol</li>
+ <li>Fixed VS.NET Compact Framework project file</li>
+ <li>Fixed the Trace target in Release mode by defining TRACE symbol</li>
+ <li>Fixed bugs related to ${asp-request:cookie} and ${aspnet-request:cookie}</li>
+ <li>Fixes for case-insensitive parsing of the config files.</li>
+ <li>fixed CompactFramework build</li>
+ </ul>
+ <p>
+ New additions:
+ </p>
+ <ul>
+ <li>Added <x><when condition="..." action="..." /></x> filter which uses condition expressions</li>
+ <li>Added <code>${aspnet-sessionid}</code> to access (guess!) ASP.NET session ID</li>
+ <li>Added ${processname}, ${processid} layout renderers</li>
+ <li>Added ASPNetBufferingWrapper target which buffers and post-processes the entire ASP.NET
+ request (requires you to use the NLogHttpModule)</li>
+ <li>Added PostFilteringWrapper target which is able to filter log events based on a buffer
+ as a whole. Details are <a href="http://sourceforge.net/mailarchive/forum.php?thread_id=8806711&forum_id=41984">here</a>.</li>
+ <li>Added GDC (Global Diagnostics Context) and ${gdc} layout renderer which
+ is a global (as opposed to per-thread) version of MDC and ${mdc}</li>
+ <li>Added authentication options to the Mail target (thanks Ron).</li>
+ <li>Added support for caching layout results per logEvent which makes them transportable across threads</li>
+ <li>Added ${log4jxmlevent} which renders <a href="http://logging.apache.org/log4j">log4j</a>-compatible XML event</li>
+ <li>Added <a href="http://www.nlog-project.org/targets.html">wrapper targets</a>: AsyncWrapper, AutoFlushWrapper, BufferingWrapper, RepeatingWrapper, RetryingWrapper</li>
+ <li>Added <a href="http://www.nlog-project.org/targets.html">compound targets</a> (fallback, randomize, roundrobin, split)</li>
+ <li>Added ${windows-identity} layout renderer.</li>
+ <li>Added MSMQ target (Message Queue)</li>
+ <li>Added EventLog target</li>
+ <li>Added ${pc} - Performance Counter layout renderer</li>
+ <li>Added SimpleConfigurator.ConfigureForTargetLogging() and SimpleConfigurator.ConfigureForFileLogging()</li>
+ <li>Added Debugger target</li>
+ <li>Added ${logger:shortname=true} option.</li>
+ <li>Added ${stacktrace} layout renderer, 3 different logging formats. Details are <a href="http://sourceforge.net/mailarchive/message.php?msg_id=12029446">here</a>.</li>
+ <li>Added ${newline} layout renderer.</li>
+ <li>Added IgnoreCase option to filters</li>
+ </ul>
+ <p>
+ Other changes:
+ </p>
+ <ul>
+ <li>Project web site has been moved to <a href="http://www.nlog-project.org/">http://www.nlog-project.org/</a></li>
+ <li>Patch by Yuri Mamrukov to simplify InternalLogger configuration from environment
+ variables and/or App.config settings. Fixes some nasty bug there.
+ More details are available <a href="http://sourceforge.net/mailarchive/forum.php?thread_id=9260106&forum_id=42511">here</a>.</li>
+ <li>Excluded NLogViewer from build and project. It will become be a separate project <a href="http://viewer.nlog-project.org/">here</a>.</li>
+ <li>Added batch NLogC compilation, added installer and nlogc binary snapshot.</li>
+ <li>Added some minimal VB.NET test code</li>
+ <li>Added some meaningful error message when a named target is not defined.</li>
+ <li>Added many unit tests</li>
+ </ul>
+ </td>
+ </tr>
+ <tr class="releasenote">
+ <td class="newsdate">2005-06-09</td><td class="newstext">
+ <p><b>NLog 0.9 has been released!</b></p>
+
+ <p>Major changes:</p>
+ <ol>
+ <li><b>API redesign/rename.</b></li>
+ <p>"Appender" has been renamed as "Target" and
+ "LayoutAppender" as "LayoutRenderer". This should make it easier for
+ people to understand the basic concepts ("layout appender" wasn't a good
+ idea). Old configuration file format is still supported. Old extension code
+ should require nothing more than a search/replace and a recompile.
+ </p>
+ <li>
+ Improved logging and non-logging speed by removing most abstraction
+ from the Logger class.
+ </li>
+ <p>
+ A single non-logging operation takes only 7
+ nanoseconds which means 140.000.000 logs/second). Logging API should remain
+ the same.
+ </p>
+ <li>
+ Changed the way the configuration file is parsed. Now elements are
+ processed top-down and you can change the order of the sections as well as
+ the elements you reference have been processed before.
+ </li>
+ </ol>
+
+ <p>Bugs fixed:</p>
+ <ol>
+ <li>Fixed an old bug where appenders were incorrectly combined into a chain.</li>
+ </ol>
+
+ <p>New additions:</p>
+ <ol>
+ <li>Network target (capable of sending messages over TCP and UDP, HTTP to be
+ supported)</li>
+ <li>Preliminary NLogViewer target and a sketchy, but already usable viewer
+ application. "Chainsaw" target should probably be added as well.</li>
+ <li>Added LogManager.GlobalThreshold</li>
+ <li>API documentation, target, layout renderer and filter documentation is
+ generated from source code comments using NDoc.</li>
+ <li>100% of public methods are commented in the source code.</li>
+ <li>Reworked the tutorial and howtos</li>
+ <li>Reworked the website.</li>
+ </ol>
+
+ </td>
+ </tr>
+ </table>
+ <last-changed-date>$LastChangedDate: 2006-09-18 14:32:45 +0200 (Pn, 18 wrz 2006) $</last-changed-date>
+</content>
diff --git a/web/runtimesupport.xml b/web/runtimesupport.xml
new file mode 100644
index 0000000..308dd5f
--- /dev/null
+++ b/web/runtimesupport.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation">
+ <h1>NLog Runtime Support</h1>
+
+ <p>
+ Single NLog.dll binary supports multiple runtimes and operating systems.
+ </p>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/snapshots.xml b/web/snapshots.xml
new file mode 100644
index 0000000..1371f7c
--- /dev/null
+++ b/web/snapshots.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="download" subid="snapshots">
+ <h1>Snapshots</h1>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
+
diff --git a/web/style.css b/web/style.css
new file mode 100644
index 0000000..9945f28
--- /dev/null
+++ b/web/style.css
@@ -0,0 +1,772 @@
+html, body
+{
+ margin: 0px;
+ background-color: white;
+ color: black;
+ font-family: Verdana;
+ font-size: 11px;
+}
+
+h1
+{
+ font-size: 19px;
+}
+
+h2
+{
+ margin-top: 30px;
+ font-size: 14pt;
+ font-weight: bold;
+}
+
+h5
+{
+ margin-top: 30px;
+ font-size: 12pt;
+ font-weight: bold;
+}
+
+h6
+{
+ font-size: 10pt;
+ font-weight: bold;
+}
+
+td.nav
+{
+ font-family: Trebuchet MS, Arial, Helv;
+ font-size: 13px;
+ font-style: normal;
+ padding: 3px;
+ width: 150px;
+}
+
+a
+{
+ color: blue;
+ background-color: inherit;
+}
+
+a:link
+{
+ color: blue;
+ background-color: inherit;
+}
+
+a:visited
+{
+ color: blue;
+ background-color: inherit;
+}
+
+a:hover
+{
+ color: blue;
+ background-color: inherit;
+}
+
+div.titleimage
+{
+ overflow: hidden;
+ width: 100%;
+ height: 83px;
+ background-image: url(title.png);
+}
+
+span.path
+{
+ font-family: Courier New;
+ color: #404080;
+ font-size: 100%;
+ font-weight: bold;
+}
+
+span.code
+{
+ font-family: Courier New;
+ color: #404080;
+ font-size: 100%;
+ font-weight: bold;
+}
+
+span.sql
+{
+ font-family: Courier New;
+ color: #0000ff;
+ font-size: 100%;
+ font-weight: bold;
+}
+
+span.class
+{
+ font-family: Courier New;
+ color: #0000c0;
+ font-size: 100%;
+ font-weight: bold;
+}
+
+li
+{
+ /* font-weight: bold; */
+ color: black;
+}
+
+span.keyword
+{
+ color: blue;
+}
+
+span.string
+{
+ color: #c00000;
+}
+
+span.operator
+{
+ color: #404040;
+}
+
+span.number
+{
+ color: #ff00ff;
+}
+
+span.type
+{
+ color: #008000;
+ font-weight: bold;
+}
+
+span.xmlattribute
+{
+ color: #ff0000;
+}
+
+span.xmlattribtext
+{
+ color: #0000ff;
+}
+
+span.xmlbracket
+{
+ color: #0000ff;
+}
+
+span.xmlelement
+{
+ color: #800000;
+}
+
+span.xmlcomment
+{
+ color: #008000;
+ font-style: italic;
+}
+
+a.nav
+{
+ display: block;
+ font-family: Tahoma, Arial, Helv;
+ font-style: normal;
+ font-weight: bold;
+ color: #202040;
+ margin: 1px;
+ width: 150px;
+ cursor: pointer; cursor: hand;
+ text-decoration: none;
+ padding-left: 4px;
+ padding-right: 4px;
+}
+
+a.nav:visited
+{
+ color: black;
+}
+
+a.nav:hover
+{
+ color: blue;
+}
+
+a.nav_selected
+{
+ display: block;
+ font-family: Tahoma, Trebuchet MS, Arial, Helv;
+ font-style: normal;
+ font-weight: bold;
+ color: #805020;
+ margin: 1px;
+ margin-left: 4px;
+ cursor: pointer; cursor: hand;
+ text-decoration: none;
+}
+
+a.nav_selected:visited
+{
+ color: black;
+}
+
+a.nav_selected:hover
+{
+ color: blue;
+}
+
+a.subnav
+{
+ display: block;
+ font-family: Trebuchet MS, Arial, Helv;
+ font-style: normal;
+ font-weight: normal;
+ font-size: 12px;
+ color: #202040;
+ margin: 1px;
+ cursor: pointer; cursor: hand;
+ text-decoration: none;
+ padding-left: 4px;
+ padding-right: 4px;
+}
+
+td.subnav_spacer
+{
+ width: 10px;
+}
+
+a.subnav:visited
+{
+ color: black;
+}
+
+a.subnav:hover
+{
+ background-color: #f0f0f0;
+}
+
+a.subnav_selected
+{
+ display: block;
+ font-family: Trebuchet MS, Arial, Helv;
+ font-style: normal;
+ font-weight: bold;
+ font-size: 12px;
+ color: black;
+ border: 1px solid #d0d0d0;
+ background-color: #ABC8E5;
+ padding-left: 4px;
+ padding-right: 4px;
+ cursor: pointer; cursor: hand;
+ text-decoration: none;
+}
+
+a.subnav_selected:visited
+{
+ color: black;
+}
+
+a.subnav_selected:hover
+{
+ color: red;
+}
+
+td.nav
+{
+}
+
+td.nav_selected
+{
+ background-color: #DFEAF5;
+ border: 1px solid #e0e0e0;
+ padding-left: 4px;
+ padding-right: 4px;
+ width: 150px;
+ font-size: 13px;
+}
+
+td.titledesc
+{
+ font-family: Verdana;
+ font-size: 12px;
+ vertical-align: bottom;
+ padding-bottom: 10px;
+ padding-right: 10px;
+}
+
+img.thinborder
+{
+ border: 1px solid #404040;
+}
+
+td.header
+{
+ margin-bottom: 0px;
+ height: 80px;
+}
+
+td.content
+{
+ font-family: Trebuchet MS, Arial, Helv;
+ font-size: 10pt;
+ padding: 20px;
+ padding-right: 20px;
+ width: 100%;
+ text-align: left;
+ background-color: white;
+}
+
+td.controls
+{
+ padding: 6px;
+ width: 170px;
+ background-color: #F2F7FC;
+ border-right: 1px solid #c0c0c0;
+ border-bottom: 1px solid #c0c0c0;
+}
+
+table.page
+{
+ /* border: 1px solid #404060; */
+}
+
+tr.spacer
+{
+ height: 10px;
+}
+
+
+td.copyright
+{
+ background-color: white;
+ padding: 4px;
+ font-size: 11px;
+ text-align: center;
+ font-family: Trebuchet MS, Arial, Helv;
+}
+
+
+td.hostedby
+{
+ background-color: #F2F7FC;
+ padding: 4px;
+ border-right: 1px solid #c0c0c0;
+}
+
+td.newsdate
+{
+ width: 100px;
+ vertical-align: top;
+ text-align: right;
+ font-weight: bold;
+ font-size: 14px;
+ padding: 4px;
+}
+
+td.newstext
+{
+ font-family: Trebuchet MS, Arial, Helv;
+ font-size: 13px;
+ padding: 4px;
+}
+
+code
+{
+ color: #000080;
+}
+
+.table table {
+ border: 1px solid #c0c0c0;
+ border-collapse: collapse;
+ font-size: 13px;
+ background-color: white;
+ width: 100%;
+}
+
+.table td {
+ border: 1px solid #c0c0c0;
+ margin: 0px;
+}
+
+.table th {
+ border: 1px solid #c0c0c0;
+ background-color: #efe8e8;
+ margin: 0px;
+}
+
+.noborder table {
+ font-size: 13px;
+}
+
+.noborder td {
+ margin: 4px;
+ padding: 4px;
+}
+
+.table tr.alternate
+{
+ background-color: #fff0f0;
+}
+
+div.summarytable
+{
+ font-family: Verdana, Arial, Helvetica, Geneva, SunSans-Regular, sans-serif;
+}
+
+.summarytable table {
+ font-size: 100%;
+ width: 100%%;
+ border-collapse: collapse;
+ background-color: white;
+ border: 1px solid #e0e0c0;
+}
+
+.summarytable th {
+ font-weight: bold;
+ width: 25%;
+ vertical-align: top;
+ padding-left: 5px;
+ padding-right: 15px;
+ text-align: left;
+}
+
+.summarytable td {
+ padding: 1px;
+ padding-right: 15px;
+}
+
+.summarytable td.section {
+ border: 1px solid #999999;
+ background-color: #f0f0e0;
+ padding: 5px;
+ font-weight: bold;
+}
+
+.summarytable tr.appender {
+ background-color: #f8f8f8;
+}
+
+table.submenu
+{
+}
+
+.benchmark-winner
+{
+ background-color: #ffffb0;
+}
+
+td.label
+{
+ font-weight: bold;
+ vertical-align: top;
+ font-size: 11px;
+}
+
+td.description
+{
+ vertical-align: top;
+ font-size: 11px;
+}
+
+.missing
+{
+ color: red;
+}
+
+code.config
+{
+ background-color: white;
+ display: block;
+ border: 1px solid #e0e0e0;
+ padding: 4px;
+}
+
+.acceptslayout
+{
+ font-family: Tahoma;
+ font-size: 11px;
+ background-color: yellow;
+ border: 1px solid #e0e000;
+ margin-right: 4px;
+ padding-left: 2px;
+ padding-right: 2px;
+ cursor: normal;
+}
+
+.acceptscondition
+{
+ font-family: Tahoma;
+ font-size: 11px;
+ background-color: yellow;
+ border: 1px solid #e0e000;
+ margin-right: 4px;
+ padding-left: 2px;
+ padding-right: 2px;
+ cursor: normal;
+}
+
+.required
+{
+ font-weight: bold;
+ color: blue;
+ text-decoration: none;
+}
+
+pre.example
+{
+ background-color: #f0f0f0;
+ /* border: 1px solid #c0c0f0; */
+ color: black;
+ padding: 4px;
+ font-size: 9pt;
+ white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */
+ white-space: -pre-wrap; /* Opera 4 - 6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation) */
+ word-wrap: break-word; /* IE 5.5+ */
+ width: 100%;
+}
+
+pre.example code
+{
+ white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */
+ white-space: -pre-wrap; /* Opera 4 - 6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation) */
+ word-wrap: break-word; /* IE 5.5+ */
+ font-family: Courier New;
+ color: black;
+}
+
+.subexample
+{
+ padding-left: 50px;
+}
+
+.subremarks
+{
+ padding-left: 50px;
+}
+
+.propertyheader
+{
+ padding-top: 2px;
+ padding-bottom: 2px;
+ display: block;
+}
+
+.propertydetails
+{
+ display: block;
+}
+
+table.paramtable
+{
+ border-collapse: collapse;
+ background-color: #ffffe0;
+ width: 100%;
+}
+
+table.subparamtable
+{
+ border-collapse: collapse;
+ background-color: #ffffff;
+ border: 1px solid #000000;
+}
+
+table.paramtable th
+{
+ color: black;
+ border: 1px solid #b0b0b0;
+ background-color: #ffff80;
+ font-size: 14px;
+}
+
+table.subparamtable th
+{
+ color: black;
+ border: 1px solid #b0b0b0;
+ background-color: #ffff90;
+ font-size: 12px;
+}
+
+td.parametername
+{
+ border: 1px solid #b0b0b0;
+ padding: 4px;
+ text-align: left;
+ vertical-align: top;
+ font-size: 9pt;
+}
+
+td.parametertype
+{
+ border: 1px solid #b0b0b0;
+ padding: 4px;
+ text-align: left;
+ vertical-align: top;
+ font-size: 9pt;
+}
+
+td.parametervalue
+{
+ border: 1px solid #b0b0b0;
+ text-align: left;
+ vertical-align: top;
+ font-size: 9pt;
+ white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */
+ white-space: -pre-wrap; /* Opera 4 - 6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation) */
+ word-wrap: break-word; /* IE 5.5+ */
+}
+
+td.parametervalue2
+{
+ padding: 4px;
+ text-align: left;
+ vertical-align: top;
+ font-size: 9pt;
+ white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */
+ white-space: -pre-wrap; /* Opera 4 - 6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation) */
+ word-wrap: break-word; /* IE 5.5+ */
+}
+
+td.subheader
+{
+ background-color: #ffffA0;
+ border: 1px solid #b0b0b0;
+ padding: 4px;
+ text-align: left;
+ vertical-align: top;
+ font-size: 12px;
+}
+
+hr
+{
+ color: #0000ff;
+ height: 1px;
+}
+
+table.listtable
+{
+ border-collapse: collapse;
+ background-color: #ffffe0;
+}
+
+.listtable th
+{
+ color: black;
+ border: 1px solid #b0b0b0;
+ background-color: #ffff80;
+ font-size: 14px;
+ padding: 2px;
+}
+
+.listtable td
+{
+ border: 1px solid #b0b0b0;
+ padding: 4px;
+ text-align: center;
+ vertical-align: center;
+ font-size: 12px;
+}
+
+.listtable td.name
+{
+ border: 1px solid #b0b0b0;
+ padding: 4px;
+ text-align: left;
+ vertical-align: top;
+ font-size: 12px;
+}
+
+.listtable td.description
+{
+ border: 1px solid #b0b0b0;
+ padding: 4px;
+ text-align: left;
+ vertical-align: top;
+ font-size: 12px;
+}
+
+table.definedin
+{
+ font-size: 12px;
+ border-collapse: collapse;
+}
+
+.definedin td
+{
+ margin: 0px;
+ padding: 4px;
+ border: 1px solid #c0c0c0;
+}
+
+#googleads
+{
+ position: absolute;
+ top: 90px;
+ right: 10px;
+}
+
+.underconstruction
+{
+ color: black;
+ font-size: 12px;
+ display: block;
+ padding: 4px;
+ background-color: #ffffc0;
+ border: 1px solid #ffc0c0;
+}
+
+#googlesearch
+{
+ position: absolute;
+ top: 4px;
+ right: 10px;
+}
+
+.lastupdated
+{
+ margin-top: 4px;
+ font-size: 10px;
+ padding: 2px;
+ border: 1px solid #c0c0c0;
+ background-color: white;
+ color: black;
+}
+
+.altreleasenote
+{
+ background-color: #e0e0ff;
+}
+
+.releasenote
+{
+ background-color: #c0c0ff;
+}
+
+img.out_link
+{
+ margin-left: 4px;
+}
+
+.plaincontent
+{
+ padding: 10px;
+}
+
+ at media print
+{
+ .controls
+ {
+ display: none;
+ }
+ #googlesearch
+ {
+ display: none;
+ }
+ #counterCode
+ {
+ display: none;
+ }
+}
diff --git a/web/style.xsl b/web/style.xsl
new file mode 100644
index 0000000..42a59a0
--- /dev/null
+++ b/web/style.xsl
@@ -0,0 +1,669 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:param name="page_id_override"></xsl:param>
+ <xsl:param name="subpage_id_override"></xsl:param>
+ <xsl:param name="file_extension">xml</xsl:param>
+ <xsl:param name="sourceforge">0</xsl:param>
+ <xsl:param name="log4net_comparison">0</xsl:param>
+ <xsl:param name="build_time">2006-01-01</xsl:param>
+ <xsl:param name="mode">web</xsl:param>
+ <xsl:param name="nlog_package">temp</xsl:param>
+
+ <xsl:variable name="page_id" select="concat(/*[position()=1]/@id,$page_id_override)" />
+ <xsl:variable name="subpage_id" select="concat(/*[position()=1]/@subid,$subpage_id_override)" />
+ <xsl:variable name="common" select="document(concat($mode,'.menu'))" />
+
+ <xsl:output method="xml" indent="no" omit-xml-declaration="yes" />
+
+ <xsl:template match="/">
+ <html>
+ <head>
+ <xsl:apply-templates select="//base" />
+ <link rel="stylesheet" href="style.css" type="text/css" />
+ <link rel="stylesheet" href="syntax.css" type="text/css" />
+ <link rel="icon" href="http://www.nlog-project.org/favicon.ico" type="image/x-icon" />
+ <link rel="shortcut icon" href="http://www.nlog-project.org/favicon.ico" type="image/x-icon" />
+ <meta name="generator" content="NAnt 0.85 style task" />
+ <meta name="keywords" content="NLog logging tracing debugging library easy simple C# .NET log4net log4j Logger C/C++ COM" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>NLog - <xsl:value-of select="$common/common/navigation/nav[@href=$page_id]/@label" /></title>
+ </head>
+ <body width="100%">
+ <xsl:choose>
+ <xsl:when test="$mode='plain'">
+ <div class="plaincontent">
+ <xsl:apply-templates select="/" mode="content" />
+ </div>
+ </xsl:when>
+ <xsl:otherwise>
+ <img src="title.png" style="display: none" /> <!-- need this for CHM -->
+ <div class="titleimage" style="overflow: hidden; width: 100%">
+ <img src="NLog.jpg" />
+ </div>
+ <table class="page" cellpadding="0" cellspacing="0" style="table-layout: fixed">
+ <tr>
+ <td valign="top" class="controls" rowspan="2">
+ <xsl:call-template name="controls" />
+ <p/>
+ <xsl:comment>#include virtual="/dynamic/snippet.cgi?rectbanner"</xsl:comment>
+ <div class="lastupdated">
+ Last updated: <xsl:value-of select="$build_time" />
+ <p/>
+ This website is based on <b>NLog v<xsl:value-of select="$nlog_package" /></b>.
+ Click <a href="http://www.nlog-project.org/snapshots/">here</a> to view the documentation
+ for other versions.
+ </div>
+ </td>
+ <td valign="top" align="left" class="content">
+ <xsl:comment>#include virtual="/dynamic/snippet.cgi?vertbanner"</xsl:comment>
+ <xsl:comment>#include virtual="/dynamic/snippet.cgi?topbanner"</xsl:comment>
+ <xsl:apply-templates select="/" mode="content" />
+ <xsl:apply-templates select="/content/last-changed-date" mode="lastchangeddate" />
+ <xsl:comment>#include virtual="/dynamic/snippet.cgi?bottombanner"</xsl:comment>
+ </td>
+ </tr>
+ <tr>
+ <td class="copyright">Copyright © 2004-2006 by Jaros³aw Kowalski.</td>
+ </tr>
+ </table>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="$mode = 'web'">
+ <div id="googlesearch">
+ <!-- SiteSearch Google -->
+ <form method="get" action="http://www.google.com/custom" target="_top">
+ <table border="0">
+ <tr><td nowrap="nowrap" valign="top" align="left" height="32">
+<input type="hidden" name="domains" value="www.nlog-project.org"></input>
+<input type="text" name="q" size="20" maxlength="255" value=""></input>
+<input type="submit" name="sa" value="Google Search"></input>
+</td></tr>
+<tr>
+<td nowrap="nowrap">
+<table>
+<tr>
+<td>
+<input type="radio" name="sitesearch" value=""></input>
+<font size="-1" color="#000080">Web</font>
+</td>
+<td>
+<input type="radio" name="sitesearch" value="www.nlog-project.org" checked="checked"></input>
+<font size="-1" color="#000080">www.nlog-project.org</font>
+</td>
+</tr>
+</table>
+<input type="hidden" name="forid" value="1"></input>
+<input type="hidden" name="ie" value="UTF-8"></input>
+<input type="hidden" name="oe" value="UTF-8"></input>
+<input type="hidden" name="cof" value="GALT:#0066CC;GL:1;DIV:#999999;VLC:336633;AH:center;BGC:FFFFFF;LBGC:FF9900;ALC:0066CC;LC:0066CC;T:000000;GFNT:666666;GIMP:666666;FORID:1;"></input>
+<input type="hidden" name="hl" value="en"></input>
+</td></tr></table>
+</form>
+<!-- SiteSearch Google -->
+ </div>
+ <div id="counterCode">
+ <!-- Start of StatCounter Code -->
+ <script type="text/javascript" language="javascript">
+ var sc_project=575077;
+ var sc_partition=4;
+ var sc_security="6fe22c9a";
+ </script>
+
+ <script type="text/javascript" language="javascript" src="http://www.statcounter.com/counter/counter.js"></script><noscript><a href="http://www.statcounter.com/" target="_blank"><img src="http://c5.statcounter.com/counter.php?sc_project=575077&java=0&security=6fe22c9a" alt="website tracking" border="0" /></a> </noscript>
+ <!-- End of StatCounter Code -->
+ <!-- Google Analytics -->
+ <script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
+ </script>
+ <script type="text/javascript">
+ _uacct = "UA-256960-2";
+ urchinTracker();
+ </script>
+ <!-- End of Google Analytics -->
+ </div>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template name="nlog-package-name" match="nlog-package-name">
+ <xsl:value-of select="$nlog_package" />
+</xsl:template>
+
+<xsl:template match="@* | node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@* | node()" />
+ </xsl:copy>
+</xsl:template>
+
+ <xsl:template match="content" mode="content">
+ <xsl:apply-templates select="*" />
+ </xsl:template>
+
+ <xsl:template name="controls">
+ <xsl:apply-templates select="$common/common/navigation" />
+ </xsl:template>
+
+ <xsl:template match="code[@lang]">
+ <pre class="example">
+ <xsl:copy-of select="." />
+ </pre>
+ </xsl:template>
+
+ <xsl:template match="navigation">
+ <table border="0" cellpadding="0" cellspacing="0">
+ <xsl:apply-templates select="nav" />
+ </table>
+ </xsl:template>
+
+ <xsl:template match="a[starts-with(@href,'http://') and not(starts-with(@href,'http://www.nlog-project')) and not(@nomangle)]">
+ <a href="http://www.nlog-project.org/external/{substring-after(@href,'http://')}">
+ <xsl:apply-templates />
+ </a>
+ <xsl:if test="$mode!='plain'">
+ <img class="out_link" src="out_link.gif" />
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="nav">
+ <xsl:choose>
+ <xsl:when test="$page_id = @href"><tr><td class="nav_selected"><a class="nav_selected"><xsl:attribute name="href"><xsl:value-of select="@href" />.<xsl:value-of select="$file_extension" /></xsl:attribute><xsl:value-of select="@label" /></a><table class="submenu" width="100%"><xsl:apply-templates select="subnav" /></table></td></tr></xsl:when>
+ <xsl:otherwise>
+ <tr><td class="nav"><a class="nav"><xsl:attribute name="href"><xsl:value-of select="@href" /><xsl:if test="not(@noext)">.<xsl:value-of select="$file_extension" /></xsl:if></xsl:attribute><xsl:value-of select="@label" /></a></td></tr>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="subnav">
+ <xsl:choose>
+ <xsl:when test="$subpage_id = @href"><tr><td><a class="subnav_selected" href="{@href}.{$file_extension}"><xsl:value-of select="@label" /></a></td></tr></xsl:when>
+ <xsl:otherwise>
+ <tr><td><a class="subnav"><xsl:attribute name="href"><xsl:value-of select="@href" /><xsl:if test="not(@noext)">.<xsl:value-of select="$file_extension" /></xsl:if></xsl:attribute><xsl:value-of select="@label" /></a></td></tr>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="simple-type-name">
+ <xsl:param name="type" />
+
+ <xsl:choose>
+ <xsl:when test="contains($type,'.')">
+ <xsl:call-template name="simple-type-name">
+ <xsl:with-param name="type" select="substring-after($type,'.')" />
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="$type = 'Int32'">integer</xsl:when>
+ <xsl:when test="$type = 'String'">string</xsl:when>
+ <xsl:when test="$type = 'Boolean'">boolean</xsl:when>
+ <xsl:when test="contains($type,'#')"><xsl:value-of select="substring-after($type,'#')" /></xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$type" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:include href="syntax.xsl" />
+
+ <!--
+ static string MakeCamelCase(string s)
+ {
+ if (s.Length < 1)
+ return s.ToLower();
+
+ int firstLower = s.Length;
+ for (int i = 0; i < s.Length; ++i)
+ {
+ if (Char.IsLower(s[i]))
+ {
+ firstLower = i;
+ break;
+ }
+ }
+
+ if (firstLower == 0)
+ return s;
+
+ // DBType
+ if (firstLower != 1 && firstLower != s.Length)
+ firstLower = firstLower - 1;
+ return s.Substring(0, firstLower).ToLower() + s.Substring(firstLower);
+ }
+
+ -->
+
+ <xsl:template name="isLower">
+ <xsl:param name="char" />
+ <xsl:variable name="lowerCase" select="translate($char,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')" />
+
+ <xsl:choose>
+ <xsl:when test="$char=$lowerCase">1</xsl:when>
+ <xsl:otherwise>0</xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="firstLower">
+ <xsl:param name="text" />
+ <xsl:param name="pos">0</xsl:param>
+
+ <xsl:variable name="isLower">
+ <xsl:call-template name="isLower">
+ <xsl:with-param name="char" select="substring($text,$pos+1,$pos+1)"></xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="$isLower=1"><xsl:value-of select="$pos" /></xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="firstLower">
+ <xsl:with-param name="text" select="$text" />
+ <xsl:with-param name="pos" select="$pos + 1" />
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="camelCase">
+ <xsl:param name="text" />
+ <xsl:variable name="textLength" select="string-length($text)" />
+
+ <xsl:variable name="firstLower"><xsl:call-template name="firstLower">
+ <xsl:with-param name="text" select="$text" />
+ </xsl:call-template></xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$textLength <= 1"><xsl:value-of select="translate($text,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')" /></xsl:when>
+ <xsl:when test="$firstLower = 0"><xsl:value-of select="$text" /></xsl:when>
+ <xsl:when test="$firstLower = 1 or $firstLower = $textLength">
+ <xsl:value-of select="translate(substring($text,1,$firstLower),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')" />
+ <xsl:value-of select="substring($text,$firstLower+1)" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="translate(substring($text,1,$firstLower - 1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')" />
+ <xsl:value-of select="substring($text,$firstLower)" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="camel">
+ <xsl:call-template name="camelCase">
+ <xsl:with-param name="text"><xsl:apply-templates /></xsl:with-param>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template name="parameter_info">
+ <tr>
+ <td class="parametername">
+ <span>
+ <xsl:if test="attribute/@name='NLog.Config.RequiredParameterAttribute'">
+ <xsl:attribute name="class">required</xsl:attribute>
+ </xsl:if>
+ <xsl:call-template name="camelCase">
+ <xsl:with-param name="text" select="@name" />
+ </xsl:call-template>
+ </span>
+ </td>
+ <td class="parametertype">
+ <nobr>
+ <xsl:call-template name="simple-type-name">
+ <xsl:with-param name="type" select="@type" />
+ </xsl:call-template>
+ <xsl:if test="attribute/@name='NLog.Config.AcceptsLayoutAttribute'">
+ <a href="layoutrenderers.html"><span class="acceptslayout" title="This parameter accepts layout specification. Click here to learn more about layouts.">${}</span></a>
+ </xsl:if>
+ <xsl:if test="attribute/@name='NLog.Config.AcceptsConditionAttribute'">
+ <a href="conditions.html"><span class="acceptscondition" title="This parameter accepts condition expressions. Click here to learn more about condition expressions.">[c()]</span></a>
+ </xsl:if>
+ </nobr>
+ </td>
+ <td class="parametervalue" width="100%">
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <td class="parametervalue2">
+ <xsl:apply-templates select="documentation/summary" />
+ <xsl:if test="attribute[@name='System.ComponentModel.DefaultValueAttribute']">
+ <p>Default value is: <code><xsl:value-of select="attribute[@name='System.ComponentModel.DefaultValueAttribute']/property[@name='Value']/@value" /></code>.</p>
+ </xsl:if>
+ <xsl:variable name="typename" select="concat('T:',translate(@type,'#','.'))" />
+ <xsl:variable name="enumnode" select="//enumeration[@id=$typename]" />
+ <xsl:if test="$enumnode">
+ <p>
+ Possible values are:
+ <ul>
+ <xsl:for-each select="$enumnode/field">
+ <li><b><code><xsl:value-of select="@name" /></code></b> - <xsl:apply-templates select="documentation/summary" /></li>
+ </xsl:for-each>
+ </ul>
+ </p>
+ </xsl:if>
+ <xsl:if test="documentation/remarks">
+ <p><xsl:apply-templates select="documentation/remarks" /></p>
+ </xsl:if>
+ <xsl:if test="documentation/example">
+ <h4>Example</h4>
+ <p><xsl:apply-templates select="documentation/example" /></p>
+ </xsl:if>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </xsl:template>
+
+
+ <xsl:template match="benchmark-table">
+ <xsl:variable name="nlog_results" select="document('nlog.results.xml')" />
+ <xsl:variable name="log4net_results" select="document('log4net.results.xml')" />
+
+ <div class="table">
+ <table width="620">
+ <col width="30%" />
+ <col width="30%" />
+ <col width="12%" />
+ <col width="12%" />
+ <xsl:if test="$log4net_comparison = '1'">
+ <col width="12%" />
+ <col width="12%" />
+ </xsl:if>
+ <tr>
+ <th rowspan="2">Appender</th>
+ <th rowspan="2">Call mode</th>
+ <th colspan="2">Results</th>
+ <xsl:if test="$log4net_comparison = '1'">
+ <th colspan="2">log4net</th>
+ </xsl:if>
+ </tr>
+ <tr>
+ <th>nanoseconds per log</th>
+ <th>logs per second</th>
+ <xsl:if test="$log4net_comparison = '1'">
+ <th>nanoseconds per log</th>
+ <th>logs per second</th>
+ </xsl:if>
+ </tr>
+ <xsl:for-each select="$nlog_results/results/test/timing">
+ <xsl:variable name="logger_name" select="../@logger" />
+ <xsl:variable name="timing_name" select="@name" />
+
+ <xsl:variable name="log4net_timing"
+ select="$log4net_results/results/test[@logger=$logger_name]/timing[@name=$timing_name]" />
+
+ <tr>
+ <td><xsl:value-of select="$logger_name" /></td>
+ <td><xsl:value-of select="$timing_name" /></td>
+ <td>
+ <xsl:if test="$log4net_comparison = '1'">
+ <xsl:if test="@nanosecondsPerLog < $log4net_timing/@nanosecondsPerLog">
+ <xsl:attribute name="class">benchmark-winner</xsl:attribute>
+ </xsl:if>
+ </xsl:if>
+ <xsl:value-of select="@nanosecondsPerLog" /></td>
+ <td>
+ <xsl:if test="$log4net_comparison = '1'">
+ <xsl:if test="@nanosecondsPerLog < $log4net_timing/@nanosecondsPerLog">
+ <xsl:attribute name="class">benchmark-winner</xsl:attribute>
+ </xsl:if>
+ </xsl:if>
+ <xsl:value-of select="@logsPerSecond" /></td>
+ <xsl:if test="$log4net_comparison = '1'">
+ <td>
+ <xsl:if test="@nanosecondsPerLog > $log4net_timing/@nanosecondsPerLog">
+ <xsl:attribute name="class">benchmark-winner</xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="$log4net_timing/@nanosecondsPerLog" /></td>
+ <td>
+ <xsl:if test="@nanosecondsPerLog > $log4net_timing/@nanosecondsPerLog">
+ <xsl:attribute name="class">benchmark-winner</xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="$log4net_timing/@logsPerSecond" /></td>
+ </xsl:if>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </div>
+ </xsl:template>
+
+ <xsl:template name="detailssupportmatrix">
+ <div class="listtable">
+ <table>
+ <tr>
+ <th rowspan="2">Assembly</th>
+ <th rowspan="2">Class</th>
+ <th colspan="3">.NET Framework</th>
+ <th colspan="2">.NET CF</th>
+ <th colspan="2">Mono on Windows</th>
+ <th colspan="2">Mono on Unix</th>
+ </tr>
+ <tr>
+ <th>1.0</th>
+ <th>1.1</th>
+ <th>2.0</th>
+ <th>1.0</th>
+ <th>2.0</th>
+ <th>1.0</th>
+ <th>2.0</th>
+ <th>1.0</th>
+ <th>2.0</th>
+ </tr>
+ <tr>
+ <td><xsl:value-of select="../../@name" /></td>
+ <td><xsl:value-of select="substring-after(@id,'T:')" /></td>
+
+ <xsl:call-template name="supportmatrixvalues" />
+ </tr>
+ </table>
+ </div>
+ </xsl:template>
+
+ <xsl:template name="supportmatrixheader">
+ <tr>
+ <th rowspan="2">Name</th>
+ <th rowspan="2">Description</th>
+ <th colspan="3">.NET Framework</th>
+ <th colspan="2">.NET CF</th>
+ <th colspan="2">Mono on Windows</th>
+ <th colspan="2">Mono on Unix</th>
+ </tr>
+ <tr>
+ <th>1.0</th>
+ <th>1.1</th>
+ <th>2.0</th>
+ <th>1.0</th>
+ <th>2.0</th>
+ <th>1.0</th>
+ <th>2.0</th>
+ <th>1.0</th>
+ <th>2.0</th>
+ </tr>
+ </xsl:template>
+
+ <!-- returns a string containing '*' character if the 'attribute' matches
+ the specified framework and OS -->
+
+ <xsl:template match="attribute" mode="supported-runtime-matches">
+ <xsl:param name="framework" />
+ <xsl:param name="frameworkVersion" />
+ <xsl:param name="os" />
+ <xsl:param name="osVersion" />
+ <xsl:param name="mode" />
+
+ <xsl:variable name="attrFramework" select="property[@name='Framework']/@value" />
+ <xsl:variable name="attrOS" select="property[@name='OS']/@value" />
+ <xsl:variable name="attrMinRuntimeVersion" select="property[@name='MinRuntimeVersion']/@value" />
+ <xsl:variable name="attrMaxRuntimeVersion" select="property[@name='MaxRuntimeVersion']/@value" />
+ <xsl:variable name="attrMinOSVersion" select="property[@name='MinOSVersion']/@value" />
+ <xsl:variable name="attrMaxOSVersion" select="property[@name='MaxOSVersion']/@value" />
+
+ <xsl:variable name="result">
+ I:
+ <xsl:value-of select="$framework" />
+ A:
+ <xsl:value-of select="$attrFramework" />
+ <xsl:choose>
+ <xsl:when test="not($framework)">F1</xsl:when>
+ <xsl:when test="not($attrFramework)">F1</xsl:when>
+ <xsl:when test="$attrFramework = 'RuntimeFramework.Any'">F1</xsl:when>
+ <xsl:when test="$attrFramework = $framework">F1</xsl:when>
+ <xsl:otherwise>F0</xsl:otherwise>
+ </xsl:choose>
+ <xsl:choose>
+ <xsl:when test="not($os)">O1</xsl:when>
+ <xsl:when test="not($attrOS)">O1</xsl:when>
+ <xsl:when test="$os = 'RuntimeOS.AnyWindows' and $attrOS='RuntimeOS.Windows'">O1</xsl:when>
+ <xsl:when test="$os = 'RuntimeOS.AnyWindows' and $attrOS='RuntimeOS.WindowsNT'">O1</xsl:when>
+ <xsl:when test="$attrOS = 'RuntimeOS.Any'">O1</xsl:when>
+ <xsl:when test="$attrOS = $os">O1</xsl:when>
+ <xsl:otherwise>O0</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:value-of select="$result" />
+
+ <xsl:choose>
+ <xsl:when test="contains($result,'0')">N</xsl:when>
+ <xsl:otherwise>*</xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="supported-on">
+ <xsl:param name="framework" />
+ <xsl:param name="frameworkVersion" />
+ <xsl:param name="os" />
+ <xsl:param name="osVersion" />
+
+ <xsl:variable name="supportedAttributes" select="attribute[@name='NLog.Config.SupportedRuntimeAttribute']" />
+ <xsl:variable name="notSupportedAttributes" select="attribute[@name='NLog.Config.NotSupportedRuntimeAttribute']" />
+
+ <xsl:variable name="supportedAttributeMatches">
+ <xsl:apply-templates select="$supportedAttributes" mode="supported-runtime-matches">
+ <xsl:with-param name="framework"><xsl:value-of select="$framework" /></xsl:with-param>
+ <xsl:with-param name="os"><xsl:value-of select="$os" /></xsl:with-param>
+ <xsl:with-param name="frameworkVersion"><xsl:value-of select="$frameworkVersion" /></xsl:with-param>
+ <xsl:with-param name="osVersion"><xsl:value-of select="$osVersion" /></xsl:with-param>
+ <xsl:with-param name="mode">1</xsl:with-param>
+ </xsl:apply-templates>
+ </xsl:variable>
+
+ <xsl:variable name="notSupportedAttributeMatches">
+ <xsl:apply-templates select="$notSupportedAttributes" mode="supported-runtime-matches">
+ <xsl:with-param name="framework"><xsl:value-of select="$framework" /></xsl:with-param>
+ <xsl:with-param name="os"><xsl:value-of select="$os" /></xsl:with-param>
+ <xsl:with-param name="frameworkVersion"><xsl:value-of select="$frameworkVersion" /></xsl:with-param>
+ <xsl:with-param name="osVersion"><xsl:value-of select="$osVersion" /></xsl:with-param>
+ <xsl:with-param name="mode">0</xsl:with-param>
+ </xsl:apply-templates>
+ </xsl:variable>
+
+ <td class="support">
+ <!--
+ S[<xsl:value-of select="$supportedAttributeMatches" />]
+ NS[<xsl:value-of select="$notSupportedAttributeMatches" />]
+ -->
+ <xsl:choose>
+ <xsl:when test="$supportedAttributeMatches='' and $notSupportedAttributeMatches=''"><img src="yes.gif" /></xsl:when>
+ <xsl:when test="contains($supportedAttributeMatches,'*') and not(contains($notSupportedAttributeMatches,'*'))"><img src="yes.gif" /></xsl:when>
+ <xsl:when test="$supportedAttributeMatches='' and not(contains($notSupportedAttributeMatches,'*'))"><img src="yes.gif" /></xsl:when>
+ <xsl:otherwise> </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ </xsl:template>
+
+ <xsl:template name="supportmatrixvalues">
+ <xsl:call-template name="supported-on">
+ <xsl:with-param name="framework">RuntimeFramework.DotNetFramework</xsl:with-param>
+ <xsl:with-param name="frameworkVersion">1.0</xsl:with-param>
+ <xsl:with-param name="os">RuntimeOS.AnyWindows</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="supported-on">
+ <xsl:with-param name="framework">RuntimeFramework.DotNetFramework</xsl:with-param>
+ <xsl:with-param name="frameworkVersion">1.1</xsl:with-param>
+ <xsl:with-param name="os">RuntimeOS.AnyWindows</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="supported-on">
+ <xsl:with-param name="framework">RuntimeFramework.DotNetFramework</xsl:with-param>
+ <xsl:with-param name="frameworkVersion">2.0</xsl:with-param>
+ <xsl:with-param name="os">RuntimeOS.AnyWindows</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="supported-on">
+ <xsl:with-param name="framework">RuntimeFramework.DotNetCompactFramework</xsl:with-param>
+ <xsl:with-param name="frameworkVersion">1.0</xsl:with-param>
+ <xsl:with-param name="os">RuntimeOS.WindowsCE</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="supported-on">
+ <xsl:with-param name="framework">RuntimeFramework.DotNetCompactFramework</xsl:with-param>
+ <xsl:with-param name="frameworkVersion">2.0</xsl:with-param>
+ <xsl:with-param name="os">RuntimeOS.WindowsCE</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="supported-on">
+ <xsl:with-param name="framework">RuntimeFramework.Mono</xsl:with-param>
+ <xsl:with-param name="frameworkVersion">1.0</xsl:with-param>
+ <xsl:with-param name="os">RuntimeOS.AnyWindows</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="supported-on">
+ <xsl:with-param name="framework">RuntimeFramework.Mono</xsl:with-param>
+ <xsl:with-param name="frameworkVersion">2.0</xsl:with-param>
+ <xsl:with-param name="os">RuntimeOS.AnyWindows</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="supported-on">
+ <xsl:with-param name="framework">RuntimeFramework.Mono</xsl:with-param>
+ <xsl:with-param name="frameworkVersion">1.0</xsl:with-param>
+ <xsl:with-param name="os">RuntimeOS.Unix</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="supported-on">
+ <xsl:with-param name="framework">RuntimeFramework.Mono</xsl:with-param>
+ <xsl:with-param name="frameworkVersion">2.0</xsl:with-param>
+ <xsl:with-param name="os">RuntimeOS.Unix</xsl:with-param>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="link">
+ <a href="{@href}.{$file_extension}"><xsl:apply-templates /></a>
+ </xsl:template>
+
+ <xsl:template name="last-component">
+ <xsl:param name="t" />
+ <xsl:choose>
+ <xsl:when test="contains($t,'.')"><xsl:call-template name="last-component"><xsl:with-param name="t" select="substring-after($t,'.')" /></xsl:call-template></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$t" /></xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="see[@cref]">
+ <xsl:call-template name="last-component">
+ <xsl:with-param name="t" select="@cref" />
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="faq-index">
+ <ol>
+ <xsl:for-each select="//faq">
+ <li><a href="#faq{generate-id(.)}"><xsl:apply-templates select="faq-question" /></a></li>
+ </xsl:for-each>
+ </ol>
+ </xsl:template>
+
+ <xsl:template match="faq">
+ <hr />
+ <a name="faq{generate-id(.)}"></a>
+ <p>
+ <b><xsl:apply-templates select="faq-question" /></b>
+ <br/>
+ <xsl:apply-templates select="faq-answer" />
+ </p>
+ </xsl:template>
+
+ <xsl:template match="faq-question">
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="faq-answer">
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="last-changed-date">
+ </xsl:template>
+
+ <xsl:template match="last-changed-date" mode="lastchangeddate">
+ <xsl:variable name="lastUpdated"><xsl:value-of select="substring(.,18,20)" /></xsl:variable>
+ <xsl:if test="string-length($lastUpdated)=20"><p style="font-size: 80%">Last updated: <xsl:value-of select="$lastUpdated" /></p></xsl:if>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/web/support.xml b/web/support.xml
new file mode 100644
index 0000000..614053c
--- /dev/null
+++ b/web/support.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="support">
+ <h1>Support</h1>
+ <p>
+ The following support options are available for NLog:
+ </p>
+ <ul>
+ <li><link href="mailinglists">Mailing Lists</link> and <a href="http://www.nabble.com/NLog-Forum-f6167.html">Forum</a> where you can ask questions about NLog usage.</li>
+ <li><a href="http://trac.nlog-project.org/nlog/">TRAC interface</a> where you can report bugs and feature requests.</li>
+ </ul>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/syntax.css b/web/syntax.css
new file mode 100644
index 0000000..700de7e
--- /dev/null
+++ b/web/syntax.css
@@ -0,0 +1,151 @@
+pre.csharp
+{
+ font-family: Consolas, Courier New;
+ font-size: 9pt;
+ font-color: #606060;
+ /* border: 1px solid #e0e0e0; */
+ white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */
+ white-space: -pre-wrap; /* Opera 4 - 6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation) */
+ word-wrap: break-word; /* IE 5.5+ */
+ padding: 4pt;
+ background-color: #f0f0ff;
+}
+
+pre.XML
+{
+ font-family: Consolas, Courier New;
+ font-size: 9pt;
+ font-color: #606060;
+ white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */
+ white-space: -pre-wrap; /* Opera 4 - 6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation) */
+ word-wrap: break-word; /* IE 5.5+ */
+ padding: 4pt;
+ background-color: #f0f0ff;
+}
+
+pre.SQL
+{
+ font-family: Consolas, Courier New;
+ font-size: 9pt;
+ font-color: #606060;
+ white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */
+ white-space: -pre-wrap; /* Opera 4 - 6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation) */
+ word-wrap: break-word; /* IE 5.5+ */
+ padding: 4pt;
+ background-color: #f0f0ff;
+}
+
+.csharp .k
+{
+ color: #0000ff;
+}
+
+.csharp .c
+{
+ color: #008000;
+}
+
+.csharp .s
+{
+ color: #C00000;
+}
+
+.csharp .r
+{
+ color: #400000;
+}
+
+.jscript .k
+{
+ color: #0000ff;
+}
+
+.jscript .c
+{
+ color: #008000;
+}
+
+.jscript .s
+{
+ color: #400000;
+}
+
+.jscript .r
+{
+ color: #400000;
+}
+
+.xml .a
+{
+ color: #ff0000;
+}
+
+.xml .at
+{
+ color: #0000ff;
+}
+
+.xml .b
+{
+ color: #0000ff;
+}
+
+.xml .e
+{
+ color: #800000;
+}
+
+.xml .c
+{
+ color: #008000;
+}
+
+.xml .x
+{
+ color: #A0A000;
+}
+
+ at media print
+{
+ .downloadlink { display: none; }
+ pre.xml
+ {
+ overflow: hidden;
+ word-wrap: break-word;
+ }
+ pre.csharp
+ {
+ overflow: hidden;
+ word-wrap: break-word;
+ }
+}
+
+table.embeddedsource
+{
+ table-layout: fixed;
+}
+
+div.embeddedsource
+{
+ position: relative;
+}
+
+div.sourcecode
+{
+ border-left: 1px solid #c0c0c0;
+ border-top: 1px solid #c0c0c0;
+ border-right: 1px solid #c0c0c0;
+ border-bottom: 1px solid #c0c0c0;
+ background-color: #fffff8;
+ width: 100%;
+}
+
+.downloadlink
+{
+}
diff --git a/web/syntax.xsl b/web/syntax.xsl
new file mode 100644
index 0000000..3f905c7
--- /dev/null
+++ b/web/syntax.xsl
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:param name="external-base">../build/net-1.1-debug/web</xsl:param>
+
+ <xsl:template name="external-iframe">
+ <div class="embeddedsource">
+ <div class="sourcecode">
+ <xsl:copy-of select="document(concat($external-base,'/', at src,'.xhtml'))" />
+ </div>
+ <div class="downloadlink">
+ <a href="{@src}">Download this file</a>
+ </div>
+ </div>
+ </xsl:template>
+
+ <xsl:template match="cs[@src]">
+ <xsl:call-template name="external-iframe" />
+ </xsl:template>
+
+ <xsl:template match="js[@src]">
+ <xsl:call-template name="external-iframe" />
+ </xsl:template>
+
+ <xsl:template match="xml[@src]">
+ <xsl:call-template name="external-iframe" />
+ </xsl:template>
+
+ <xsl:template match="x">
+ <xsl:apply-templates mode="xml-example" />
+ </xsl:template>
+
+ <xsl:template match="link">
+ <a href="{@href}.{$file_extension}"><xsl:apply-templates /></a>
+ </xsl:template>
+
+ <xsl:template match="*" mode="xml-example">
+ <xsl:choose>
+ <xsl:when test="count(descendant::node()) = 0">
+ <span class="xmlbracket"><</span>
+ <span class="xmlelement"><xsl:value-of select="name()" /></span>
+ <xsl:apply-templates select="@*" mode="xml-example" />
+ <span class="xmlbracket"> /></span>
+ </xsl:when>
+ <xsl:otherwise>
+ <span class="xmlbracket"><</span>
+ <span class="xmlelement"><xsl:value-of select="name()" /></span>
+ <xsl:apply-templates select="@*" mode="xml-example" />
+ <span class="xmlbracket">></span>
+ <xsl:apply-templates mode="xml-example" />
+ <span class="xmlbracket"></</span>
+ <span class="xmlelement"><xsl:value-of select="name()" /></span>
+ <span class="xmlbracket">></span>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="@*[name()='xml:space']" mode="xml-example"></xsl:template>
+ <xsl:template match="@*" mode="xml-example">
+ <span class="xmlattribute"><xsl:text> </xsl:text><xsl:value-of select="name()"/></span>
+ <span class="xmlpunct">=</span><span class="xmlattribtext">"<xsl:value-of select="." />"</span>
+ </xsl:template>
+
+ <xsl:template match="comment()" mode="xml-example">
+ <span class="xmlcomment"><!--<xsl:value-of select="." />--></span>
+ </xsl:template>
+ <xsl:template match="node()" mode="xml-example" priority="-10">
+ <xsl:copy>
+ <xsl:apply-templates mode="xml-example" />
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="xml[@src]" mode="slashdoc">
+ <xsl:call-template name="external-iframe" />
+ </xsl:template>
+
+ <xsl:template match="js[@src]" mode="slashdoc">
+ <xsl:call-template name="external-iframe" />
+ </xsl:template>
+
+ <xsl:template match="cs[@src]" mode="slashdoc">
+ <xsl:call-template name="external-iframe" />
+ </xsl:template>
+
+ <xsl:template match="ndoc" mode="header-section">
+ <link rel="stylesheet" type="text/css" href="syntax.css" />
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/web/targets.xsl b/web/targets.xsl
new file mode 100644
index 0000000..0575ab6
--- /dev/null
+++ b/web/targets.xsl
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:param name="target_name" />
+
+ <xsl:include href="style.xsl" />
+
+ <xsl:template match="*" mode="content">
+ <xsl:if test="$target_name">
+ <xsl:apply-templates select="//class[attribute/@name='NLog.TargetAttribute' and attribute/property[@name='Name']/@value=$target_name]" mode="details">
+ <xsl:sort select="attribute[@name='NLog.TargetAttribute']/property[@name='Name']/@value" />
+ </xsl:apply-templates>
+ </xsl:if>
+ <xsl:if test="not($target_name)">
+ <h1>Log Targets</h1>
+ <p>
+ Targets represents possible log outputs. You can define one or more targets in the <link href="config">configuration file</link>
+ with the <x><target /></x> directive. When defining a target you need to specify its name and type.
+ </p>
+ <p>
+ The following types of targets are supported by NLog:
+ </p>
+ <ul>
+ <li><b><a href="#regular">Regular Targets</a></b> - which write the log messages to some output</li>
+ <li><b><a href="#wrappers">Target Wrappers</a></b> - which modify the behaviour of a target by adding
+ features such as asynchronous processing, buffering, filtering and so on.</li>
+ <li><b><a href="#compound">Compound Targets</a></b> - which route the log messages to one or more attached targets -
+ they can be used to provide failover, load balancing, log splitting and so on</li>
+ </ul>
+
+ <a name="regular"></a>
+
+ <h3>Regular Targets</h3>
+ <p>
+ Regular targets are responsible for writing log output to persistent media, such as <a href="target.File.html">files</a>,
+ <a href="target.Database.html">databases</a>, <a href="target.Network.html">network receivers</a> or <a href="target.MSMQ">message queues</a>.
+ Each target has its own set of type-specific configuration parameters which are passed as XML attributes or elements.
+ </p>
+ <p>
+ The following example defines a single file target with a file name of 'file.txt':
+ </p>
+ <pre class="XML">
+ <span style="color:#0000ff"><</span><span style="color:#800000">targets</span><span style="color:#0000ff">></span>
+ <span style="color:#0000ff"><</span><span style="color:#800000">target</span> <span style="color:#ff0000">name</span><span style="color:#0000ff">=</span><span style="color:#0000ff">"n"</span> <span style="color:#ff0000">type</span><span style="color:#0000ff">=</span><span style="color:#0000ff">"File"</span> <span style="color:#ff0000">fileName</span><span style="color:#0000ff">=</span><span style="color:#0000ff">"file.txt"</span><span style="color:#0000ff">/></span>
+<span style="color:#0000ff"></</span><span style="color:#800000">targets</span><span style="color:#0000ff">></span>
+</pre>
+
+ <p>
+ The following log targets are available. Click on a target name for a reference of possible target parameters.
+ </p>
+ <div class="noborder">
+ <table class="listtable">
+ <xsl:call-template name="supportmatrixheader" />
+ <xsl:apply-templates select="//class[attribute[@name='NLog.TargetAttribute' and not(property[@name='IsWrapper' and @value='True']) and not(property[@name='IsCompound' and @value='True'])]]" mode="list">
+ <xsl:sort select="../../@name" />
+ <xsl:sort select="attribute[@name='NLog.TargetAttribute']/property[@name='Name']/@value" />
+ </xsl:apply-templates>
+ </table>
+ </div>
+ <a name="wrappers"></a>
+ <h3>Target Wrappers</h3>
+ <p>
+ Target wrappers are used to modify the behavior of other targets by adding features such as:
+ </p>
+ <ul>
+ <li>asynchronous processing (wrapped target runs in a separate thread)</li>
+ <li>retry-on-error</li>
+ <li>buffering</li>
+ </ul>
+ <p>
+ The following target wrappers are available. Click on a target name for full reference.
+ </p>
+ <div class="noborder">
+ <table class="listtable">
+ <xsl:call-template name="supportmatrixheader" />
+ <xsl:apply-templates select="//class[attribute[@name='NLog.TargetAttribute' and property[@name='IsWrapper' and @value='True']]]" mode="list">
+ <xsl:sort select="../../@name" />
+ <xsl:sort select="attribute[@name='NLog.TargetAttribute']/property[@name='Name']/@value" />
+ </xsl:apply-templates>
+ </table>
+ </div>
+ <a name="compound"></a>
+ <h3>Compound Targets</h3>
+ <p>
+ The following compound targets are available. Click on the target name for full reference.
+ </p>
+ <div class="noborder">
+ <table class="listtable">
+ <xsl:call-template name="supportmatrixheader" />
+ <xsl:apply-templates select="//class[attribute[@name='NLog.TargetAttribute' and property[@name='IsCompound' and @value='True']]]" mode="list">
+ <xsl:sort select="../../@name" />
+ <xsl:sort select="attribute[@name='NLog.TargetAttribute']/property[@name='Name']/@value" />
+ </xsl:apply-templates>
+ </table>
+ </div>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="class" mode="list">
+ <xsl:variable name="type_tag" select="attribute[@name='NLog.TargetAttribute']/property[@name='Name']/@value" />
+ <tr>
+ <td class="name"><a href="target.{$type_tag}.html"><xsl:value-of select="$type_tag" /></a></td>
+ <td class="description"><xsl:apply-templates select="documentation/summary" /></td>
+ <xsl:call-template name="supportmatrixvalues" />
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="@* | node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@* | node()" />
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="summary">
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="class" mode="details">
+ <xsl:variable name="type_tag" select="attribute[@name='NLog.TargetAttribute']/property[@name='Name']/@value" />
+ <h3><xsl:value-of select="$type_tag" /> Target</h3>
+
+ <hr size="1" />
+ <xsl:apply-templates select="documentation/summary" /><p/>
+ <xsl:call-template name="detailssupportmatrix" />
+ <xsl:if test="documentation/remarks">
+ <h4>Remarks:</h4>
+ <xsl:apply-templates select="documentation/remarks" />
+ </xsl:if>
+ <h4>Parameters (blue fields are required):</h4>
+ <table cellspacing="0" cellpadding="0" class="paramtable">
+ <tr>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+ <xsl:apply-templates select="property" mode="parameter">
+ <xsl:sort select="count(attribute[@name='NLog.Config.RequiredParameterAttribute'])" order="descending" />
+ <xsl:sort select="@name" />
+ </xsl:apply-templates>
+ <xsl:if test="property[attribute/@name='NLog.Config.ArrayParameterAttribute']">
+ <xsl:apply-templates select="property" mode="parameter2">
+ <xsl:sort select="count(attribute[@name='NLog.Config.RequiredParameterAttribute'])" order="descending" />
+ <xsl:sort select="@name" />
+ </xsl:apply-templates>
+ </xsl:if>
+ </table>
+ <xsl:if test="documentation/example">
+ <h4>Example:</h4>
+ <xsl:apply-templates select="documentation/example" />
+ </xsl:if>
+ <hr size="1" />
+ <a href="targets.html">Back to the target list.</a>
+ </xsl:template>
+
+ <xsl:template match="property[@set='false']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@id='P:NLog.Target.Name']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@id='P:NLog.Target.Type']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@type='NLog.Layout']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@type='NLog.ILayout']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property[@type='NLog.Conditions.ConditionExpression']" mode="parameter">
+ <!-- ignore -->
+ </xsl:template>
+
+ <xsl:template match="property" mode="parameter">
+ <xsl:if test="@name != 'Layout' or not(../attribute[@name='NLog.TargetAttribute']/property[@name='IgnoresLayout']/@value='True')">
+ <xsl:call-template name="parameter_info" />
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="property[attribute/@name='NLog.Config.ArrayParameterAttribute']" mode="parameter2">
+ <xsl:variable name="itemname" select="attribute[@name='NLog.Config.ArrayParameterAttribute']/property[@name='ElementName']/@value" />
+ <xsl:variable name="itemtype" select="attribute[@name='NLog.Config.ArrayParameterAttribute']/property[@name='ItemType']/@value" />
+ <tr>
+ <td valign="top" class="parametername" rowspan="2">
+ <xsl:value-of select="@name" />
+ </td>
+ <td class="parametertype" colspan="2">
+ Collection of
+ <xsl:call-template name="simple-type-name">
+ <xsl:with-param name="type"><xsl:value-of select="$itemtype" /></xsl:with-param>
+ </xsl:call-template>. Each element is represented as <<xsl:value-of select="$itemname" />/>
+ </td>
+ </tr>
+ <tr>
+ <td class="parametervalue" colspan="2">
+ <table class="subparamtable" cellspacing="0" cellpadding="0" width="100%">
+ <tr>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+ <xsl:apply-templates select="//class[@id=concat('T:',$itemtype)]/property" mode="parameter" />
+ </table>
+ </td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="property" mode="parameter2">
+ </xsl:template>
+
+ <xsl:template match="c">
+ <code><xsl:apply-templates /></code>
+ </xsl:template>
+
+ <xsl:template match="code[@escaped='true']">
+ <code><pre class="xml-example"><xsl:apply-templates mode="xml-example" /></pre></code>
+ </xsl:template>
+
+ <xsl:template match="code">
+ <code><pre class="example"><xsl:apply-templates /></pre></code>
+ </xsl:template>
+
+ <xsl:template match="see">
+ <code><xsl:value-of select="@cref" /></code>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/web/technical.xml b/web/technical.xml
new file mode 100644
index 0000000..642a763
--- /dev/null
+++ b/web/technical.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="technical">
+ <h1>Technical Information</h1>
+ <p>
+ Here you'll find some information about the inner working of NLog.
+ </p>
+ <ol>
+ <li><a href="/clover/index.html">Latest code coverage results generated using Clover.NET (this is just a beginning of any serious unit testing so the coverage isn't very good)</a></li>
+ <li><a href="/nunit2report/">Latest NUnit testing results generated using NUnit2Report</a></li>
+ </ol>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/title.png b/web/title.png
new file mode 100644
index 0000000..b704b6b
Binary files /dev/null and b/web/title.png differ
diff --git a/web/tutorial.xml b/web/tutorial.xml
new file mode 100644
index 0000000..57f2931
--- /dev/null
+++ b/web/tutorial.xml
@@ -0,0 +1,937 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <h2>Introduction to tracing applications with NLog</h2>
+ <p>Author: Jaros³aw Kowalski <<a href="mailto:jaak at jkowalski.net">jaak at jkowalski.net</a>></p>
+ <div style="margin-left: 1cm; margin-right: 1cm">
+ <font color="#006400">
+ <i>
+ Once upon a time, when there were no debuggers in the world and software
+ was mostly console-based, programmers used to output tracing messages
+ using <a href="http://www.cplusplus.com/ref/cstdio/printf.html">printf</a>()
+ statements.
+ Today's world has seen huge advancement in technology
+ and printf() was replaced with Console.WriteLine()...
+ </i>
+ </font>
+ </div>
+ <p>
+ We've all written code similiar to the following:
+ </p>
+ <code lang="C#">
+ <![CDATA[
+ static void Main()
+ {
+ Console.WriteLine("SuperApp started.");
+ DoSomething();
+ Console.WriteLine("SuperApp finished.");
+ }]]>
+ </code>
+
+ <p>Console.WriteLine() statements in the above example are called "tracing statements"
+ because they are only used to report our application's control flow and have no
+ other function. The output of Console.WriteLine() is called the program trace.
+ In this example, the tracing statements produce output that
+ tells us if the DoSomething() method has finished execution or not.
+ </p>
+
+ <p>
+ After giving the application some testing, we tend to remove the tracing code in
+ order to improve performance (tracing can take a lot of time). Tracing instructions are
+ usually commented out so that they can be re-enabled in the future. Unfortunately
+ this requires our program to be recompiled.
+ </p>
+ <p>
+ Some time later, after removing hundreds of the comments and putting them back for the Nth time, we
+ get the feeling that our tracing solution is not perfect and we could benefit from:
+ </p>
+ <ul>
+ <li>
+ the ability to control the level of detail of our trace messages (such as displaying
+ only warnings and errors or very detailed program trace),
+ </li>
+ <li>the possibility of turning the tracing on and off for components of our proram separately,
+ without turning the application off and recompiling it,</li>
+ <li>
+ writing trace messages to the file, system log, message queue or other output,
+ </li>
+ <li>being able to send particularly important messages by email or store them in a database,
+ </li>
+ <li>and others...</li>
+ </ul>
+ <p>
+ It may seem, that in the age of graphical debuggers, the usefulness of tracing-based solutions
+ is limited. Sometimes tracing turns out to be the only tool available, which can be used
+ to locate bug in a mission-critical system that cannot be switched off for a single minute.
+ </p>
+
+ <h2>What is NLog?</h2>
+
+ <p>
+ NLog <a href="http://www.nlog-project.org/">(http://www.nlog-project.org)</a> is
+ a .NET library, which enables you to add sophisticated tracing code to your application,
+ delivering the functionality mentioned above and much, much more.
+ </p>
+ <p>
+ NLog lets you write <b>rules</b> which control the flow
+ of diagnostic traces from their <b>sources</b> to <b>targets</b>, which could be:
+ </p>
+ <ul>
+ <li>a file</li>
+ <li>text console</li>
+ <li>email message</li>
+ <li>database</li>
+ <li>other machine on the network (using TCP/UDP)</li>
+ <li>MSMQ-based message queue</li>
+ <li>Event Log</li>
+ <li>
+ and others, described in <a href="http://www.nlog-project.org/targets.html">http://www.nlog-project.org/targets.html</a>
+ </li>
+ </ul>
+ <p>
+ In addition, each tracing message can be augmented with pieces of <b>contextual information</b>,
+ which will be sent with it to the target. The contextual information can include:
+ </p>
+ <ul>
+ <li>current date and time (in various formats)</li>
+ <li>log level</li>
+ <li>soure name</li>
+ <li>stack trace/information about the method that emitted the tracing message</li>
+ <li>values of environment variables</li>
+ <li>information about exceptions</li>
+ <li>machine, process and thread names</li>
+ <li>
+ and many more, as described in <a href="http://www.nlog-project.org/layoutrenderers.html">http://www.nlog-project.org/layoutrenderers.html</a>
+ </li>
+ </ul>
+ <p>
+ Each tracing message is associated with a log level which describes its severity. NLog supports the following levels.
+ </p>
+ <ul>
+ <li>
+ <b>Trace </b>- Very detailed log messages, potentially of a high frequency and volume
+ </li>
+ <li>
+ <b>Debug </b>-Less detailed and/or less frequent debugging messages
+ </li>
+ <li>
+ <b>Info </b>- Informational messages
+ </li>
+ <li>
+ <b>Warn </b>- Warnings which don't appear to the user of the application
+ </li>
+ <li>
+ <b>Error </b>- Error messages
+ </li>
+ <li>
+ <b>Fatal </b>- Fatal error messages. After a fatal error the application usually
+ terminates.
+ </li>
+ </ul>
+ <p>
+ NLog is a open source library distributed at no cost under the terms of
+ <a href="http://svn.nlog-project.org/repos/nlog/trunk/NLog/LICENSE.txt">BSD license</a>, which permits commercial usage with almost no obligation.
+
+ You can download NLog binary and source code releases from
+ <a href="http://www.nlog-project.org/download.html">http://www.nlog-project.org/download.html</a>.
+ Graphical installer is also provided, which lets you install NLog in a preferred place and enable
+ integration with Visual Studio 2005 (Express editions are also supported), including:
+ </p>
+ <ul>
+ <li>configuration file templates</li>
+ <li>Intellisense for NLog config files</li>
+ <li>code snippets</li>
+ <li><code>Add Reference...</code> dialog integration</li>
+ </ul>
+
+ <h2>Our first NLog-enabled application</h2>
+ <p>
+ Let's create our first application that uses NLog using Visual Studio 2005. We'll start
+ with a simple example that only logs to the console, and we'll be adding features
+ that demonstrate how easy it is to control logging configuration in NLog.
+ </p>
+ <p>
+ The first step is to create a Visual Studio project (in this example we'll be using C#) and
+ add NLog configuration file using "Add New Item..." dialog. Let's add an
+ "Empty NLog Configuration File" and save it as "NLog.config":
+ </p>
+ <img src="introduction_addnewitem.gif" />
+ <p>
+ Notice how a reference to NLog.dll has automatically been added to our project. The contents of NLog.config
+ file, which we'll be modifying in this tutorial, are:
+ </p>
+
+ <code lang="XML">
+ <![CDATA[<?xml version="1.0" encoding="utf-8" ?>
+ <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ </targets>
+
+ <rules>
+ </rules>
+ </nlog>
+ ]]>
+ </code>
+
+ <p>You only need to do one more thing: Change "Copy To Output Directory" option for this
+ file to "Copy always". This way our configuration file will be placed in the same directory
+ as the *.exe file and NLog will be able to pick it up without any special configuration.
+ </p>
+ <img src="introduction_copytooutput.gif" />
+
+ <p>
+ It's time to configure log output. In the <x>
+ <targets />
+ </x> section we'll add a entry that defines console output and the required output layout:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <targets>
+ <target name="console" xsi:type="Console" layout="${longdate}|${level}|${message}" />
+ </targets>
+ ]]>
+ </code>
+ <p>
+ Notice how Visual Studio suggests the possible XML element names and attribute names/values.
+ Once we type <b>xsi:</b>, we get a list of available log targets.
+ </p>
+ <img src="introduction_target_intellisense.gif" />
+
+ <p>
+ In the <x>
+ <rules />
+ </x> section we'll add a rule that routes all message whose level is Debug or higher to the console.
+ The XML is quite self-explanatory.
+ </p>
+
+ <code lang="XML" escaped="true">
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="console" />
+ </rules>
+ </code>
+
+ <p>
+ In order to send a diagnostic message, we use a Logger object, whose methods are named after supported log
+ levels (Debug(), Info(), Fatal() and so on). Logger objects can be created thanks to the LogManager class.
+ It's recommended that logger names correspond to the full class names
+ in the application. The LogManager object has a
+ GetCurrentClassLogger() method that automatically creates a logger
+ based on the class its being called from.
+ </p>
+ <p>
+ Let's modify the wizard-generated C# file by adding "using NLog" statement at the beginning,
+ the code to create logger and example log message. Note that you can quickly type
+ the logger-creation statement by using the Code Snippet which is installed with NLog.
+ Just type "nlogger" and press TAB twice.
+ </p>
+
+ <code lang="C#">
+ <![CDATA[
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+ using NLog;
+
+ namespace NLogExample
+ {
+ class Program
+ {
+ private static Logger logger = LogManager.GetCurrentClassLogger();
+
+ static void Main(string[] args)
+ {
+ logger.Debug("Hello World!");
+ }
+ }
+ }
+ ]]>
+ </code>
+ <p>
+ The result of running this program is a message written to the console which includes
+ the current date, log level (<font face="Courier New">Debug</font>)
+ and the <font face="Courier New">Hello World</font> message.
+ </p>
+
+ <p>
+ Let's see how we achieved this:
+ </p>
+ <ol>
+ <li>
+ <a href="http://www.nlog-project.org/help/NLog.LogManager.GetCurrentClassLogger.html">LogManager.GetCurrentClassLogger();</a>
+ creates an instance of <a href="http://www.nlog-project.org/help/NLog.Logger.html">Logger</a> class which represents the <b>source</b>
+ of log messages which is associated with current class.
+ </li>
+ <li>
+ Calling the Debug() method on the source object sends the diagnostic message on the Debug level.
+ </li>
+ <li>
+ Because our log level and source name match the rule defined in <x><rules /></x>
+ section, the message gets formatted according to the "layout" specification
+ and sent to the console.
+ </li>
+ </ol>
+ <h4>
+ More advanced logging scenario
+ </h4>
+ <p>
+ Let's record our log messages, along with some contextual information
+ such as the the current stack trace, to both a file and the console. To
+ do this we need to defined another <target /> of type "File" and tell
+ the <logger /> node that we want write to it.
+ </p>
+ <code lang="XML">
+ <![CDATA[<?xml version="1.0" encoding="utf-8" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="console" xsi:type="ColoredConsole" layout="${date:format=HH\:mm\:ss}|${level}|${stacktrace}|${message}" />
+ <target name="file" xsi:type="File" fileName="${basedir}/file.txt" layout="${stacktrace} ${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Trace" writeTo="console,file" />
+ </rules>
+</nlog>
+ ]]>
+ </code>
+
+
+ <p>
+ Here's the C# source code that emits some more log messages, additional methods are
+ introduced here to observe the stack trace feature.
+ </p>
+ <code lang="C#">
+ <![CDATA[
+ static void C()
+ {
+ logger.Info("Info CCC");
+ }
+ static void B()
+ {
+ logger.Trace("Trace BBB");
+ logger.Debug("Debug BBB");
+ logger.Info("Info BBB");
+ C();
+ logger.Warn("Warn BBB");
+ logger.Error("Error BBB");
+ logger.Fatal("Fatal BBB");
+ }
+ static void A()
+ {
+ logger.Trace("Trace AAA");
+ logger.Debug("Debug AAA");
+ logger.Info("Info AAA");
+ B();
+ logger.Warn("Warn AAA");
+ logger.Error("Error AAA");
+ logger.Fatal("Fatal AAA");
+ }
+ static void Main(string[] args)
+ {
+ logger.Trace("This is a Trace message");
+ logger.Debug("This is a Debug message");
+ logger.Info("This is an Info message");
+ A();
+ logger.Warn("This is a Warn message");
+ logger.Error("This is an Error message");
+ logger.Fatal("This is a Fatal error message");
+ }
+ ]]>
+ </code>
+ <p>
+ When we run the program, the following information will be written to the "file.txt" in the application
+ directory:
+ </p>
+ <code lang="C#">
+ <![CDATA[
+Program.Main This is a Trace message
+Program.Main This is a Debug message
+Program.Main This is an Info message
+Program.Main => Program.A Trace AAA
+Program.Main => Program.A Debug AAA
+Program.Main => Program.A Info AAA
+Program.Main => Program.A => Program.B Trace BBB
+Program.Main => Program.A => Program.B Debug BBB
+Program.Main => Program.A => Program.B Info BBB
+Program.A => Program.B => Program.C Info CCC
+Program.Main => Program.A => Program.B Warn BBB
+Program.Main => Program.A => Program.B Error BBB
+Program.Main => Program.A => Program.B Fatal BBB
+Program.Main => Program.A Warn AAA
+Program.Main => Program.A Error AAA
+Program.Main => Program.A Fatal AAA
+Program.Main This is a Warn message
+Program.Main This is an Error message
+Program.Main This is a Fatal error message
+]]>
+ </code>
+ <p>At the same time, we get this fancy colored output on the console:</p>
+ <img src="introduction_coloredconsole_en.gif" />
+ <p>
+ Now let's modify our configuration a bit. The typical requirement is to have
+ a different level of detail depending on the output. For example, we only
+ want messages whose level is Info and higher written to the console
+ and we want ALL messages to be written to the file.
+ With NLog, you only need to change the <x><rules /></x>
+ section. No changes to the C# source code are necessary:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <rules>
+ <logger name="*" minlevel="Info" writeTo="console" />
+ <logger name="*" minlevel="Trace" writeTo="file" />
+ </rules>
+ ]]>
+ </code>
+ <p>
+ After running the program we find that Trace and Debug messages are
+ only found in the file and aren't displayed on the console.
+ </p>
+ <h2>Logging configuration</h2>
+ <p>
+ It's now time to describe the NLog configuration mechanism. Unlike other tools, NLog attempts
+ to automatically configure itself on startup, by looking for the configuration files in some standard places.
+ The following locations will be searched when executing a stand-alone *.exe application:
+ </p>
+ <ul>
+ <li>
+ standard application configuration file (usually <font face="Courier New">applicationname.exe.config)</font>
+ </li>
+ <li>
+ <font face="Courier New">applicationname.exe.nlog</font> in application's directory
+ </li>
+ <li>
+ <font face="Courier New">NLog.config</font> in application's directory
+ </li>
+ <li>
+ <font face="Courier New">NLog.dll.nlog</font> in a directory where <font face="Courier New">NLog.dll</font> is located
+ </li>
+ <li>
+ file name pointed by the <font face="Courier New">NLOG_GLOBAL_CONFIG_FILE</font> environment variable (if defined)
+ </li>
+ </ul>
+ <p>
+ In case of an ASP.NET application, the following files are searched:
+ </p>
+ <ul>
+ <li>
+ standard web application file <font face="Courier New">web.config</font>
+ </li>
+ <li>
+ <font face="Courier New">web.nlog</font> located in the same directory as <font face="Courier New">web.config</font>
+ </li>
+ <li>
+ <font face="Courier New">NLog.config</font> in application's directory
+ </li>
+ <li>
+ <font face="Courier New">NLog.dll.nlog</font> in a directory where <font face="Courier New">NLog.dll</font> is located
+ </li>
+ <li>
+ file name pointed by the <font face="Courier New">NLOG_GLOBAL_CONFIG_FILE</font> environment variable (if defined)
+ </li>
+ </ul>
+ <p>
+ The .NET Compact Framework doesn't recognize application configuration files (*.exe.config)
+ nor environmental variables, so NLog only looks in these locations:
+ </p>
+ <ul>
+ <li>
+ <font face="Courier New">applicationname.exe.nlog</font> in application's directory
+ </li>
+ <li>
+ <font face="Courier New">NLog.config</font> in application's directory
+ </li>
+ <li>
+ <font face="Courier New">NLog.dll.nlog</font> in a directory where <font face="Courier New">NLog.dll</font> is located
+ </li>
+ </ul>
+ <h4>Configuration file format</h4>
+ <p>
+ NLog supports two configuration file formats:
+ </p>
+ <ul>
+ <li>configuration embedded within the standard *.exe.config or web.config file</li>
+ <li>simplified configuration, stored in a separate file</li>
+ </ul>
+ <p>
+ In the first variant, we use a standard configSections mechanism, which makes our file look like this:
+ </p>
+ <code lang="XML">
+ <![CDATA[<?xml version="1.0" encoding="utf-8" ?>
+ <configuration>
+ <configSections>
+ <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
+ </configSections>
+ <nlog>
+ </nlog>
+ </configuration>
+ ]]>
+ </code>
+ <p>
+ The simplified format is the pure XML having the <x>
+ <nlog />
+ </x> element as its root.
+ The use of namespaces is optional, but it enables the Intellisense in Visual Studio.
+ </p>
+ <code lang="XML">
+ <![CDATA[<?xml version="1.0" encoding="utf-8" ?>
+ <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ </nlog>
+ ]]>
+ </code>
+ <p>
+ Note that NLog config file is case-insensitive when not using namespaces
+ and is case-sensitive when you use them. Intellisense only works with case-sensitive
+ configurations.
+ </p>
+ <h4>Configuration elements</h4>
+ <p>
+ You can use the following elements as children to <x>
+ <nlog />
+ </x>. The first two elements from the list are required to be present in all
+ NLog configuration files, the remaining ones are optional and can be useful in
+ advanced scenarios.
+ </p>
+ <ul>
+ <li>
+ <x><targets /></x> - defines log targets/outputs
+ </li>
+ <li>
+ <x><rules /></x> - defines log routing rules
+ </li>
+ <li>
+ <x><extensions /></x> - loads NLog extensions from the *.dll file
+ </li>
+ <li>
+ <x><include /></x> - includes external configuration file
+ </li>
+ <li>
+ <x><variable /></x> - sets the value of a configuration variable
+ </li>
+ </ul>
+ <h4>Targets</h4>
+ <p>
+ The <x>
+ <targets />
+ </x> section defines log targets/outputs. Each target is represented by
+ the <x><target /></x> element.
+ There are two attributes required for each target:
+ </p>
+ <ul>
+ <li>
+ <b>name</b> - target name
+ </li>
+ <li>
+ <b>type</b> - target type - such as "File", "Database", "Mail". When using namespaces this attribute is named <b>xsi:type</b>.
+ </li>
+ </ul>
+ <p>
+ In addition to these, targets usually accept other parameters, which influence the way diagnostic
+ traces are written. Each target has a different set of parameters, they are described in detail
+ on project's homepage and they are context-sensitive Intellisense is also available in Visual Studio.
+ </p>
+ <p>
+ For example - the "<b>File</b>" target accepts the <b>fileName</b> parameter which defines
+ output file name and the <b>Console</b> target has the <b>error</b> parameter which determines
+ whether the diagnostic traces are written to standard error (stderr) instead of standard output
+ (stdout) of the process.
+ </p>
+ <p>
+ NLog provides many predefined targets. They are described on the project's homepage.
+ It's actually very easy to create your own target - it requires about 15-20 lines of
+ code and is described in the
+ <a href="http://www.nlog-project.org/documentation.html">documentation</a>.
+ </p>
+ <h4>Rules</h4>
+ <p>
+ Log routing rules are defined in the <x>
+ <rules />
+ </x> section. It is a simple routing table, where we define the list of targets
+ that should be written to for each combination of source/logger name and log level.
+ Rules are processed starting with the first rule in the list. When a
+ rule matches, log messages are directed to target(s) in that rule. If a
+ rule is marked as final, rules beneath the current rule are not
+ processed.
+ </p>
+ <p>
+ Each routing table entry is a <x>
+ <logger />
+ </x> element, which accepts the following attributes:
+ </p>
+ <ul>
+ <li>
+ <font face="Courier New">name</font> - source/logger name (may include wildcard characters <b>*</b>)
+ </li>
+ <li>
+ <font face="Courier New">minlevel</font> - minimal log level for this rule to match
+ </li>
+ <li>
+ <font face="Courier New">maxlevel</font> - maximum log level for this rule to match
+ </li>
+ <li>
+ <font face="Courier New">level</font> - single log level for this rule to match
+ </li>
+ <li>
+ <font face="Courier New">levels </font>- comma separated list of log levels for this rule to match
+ </li>
+ <li>
+ <font face="Courier New">writeTo</font> - comma separated list of target that should be written to when this rule matches.
+ </li>
+ <li>
+ <font face="Courier New">final</font> - make this rule final. No further rules are processed when any
+ final rule matches.
+ </li>
+ </ul>
+ <p>
+ Some examples:
+ </p>
+ <ul>
+ <li>
+ <x>
+ <logger name="Name.Space.Class1" minlevel="Debug" writeTo="f1" />
+ </x> - all messages from the <font face="Courier New">Class1</font> in the <font face="Courier New">Name.Space</font> whose level is <font face="Courier New">Debug</font> or higher are written to the "<font face="Courier New">f1</font>" target.
+ </li>
+ <li>
+ <x>
+ <logger name="Name.Space.Class1" levels="Debug,Error" writeTo="f1" />
+ </x> - all messages from the <font face="Courier New">Class1</font> in the <font face="Courier New">Name.Space</font> whose level is either <font face="Courier New">Debug</font> or <font face="Courier New">Error</font> or higher are written to the "<font face="Courier New">f1</font>" target.
+ </li>
+ <li>
+ <x>
+ <logger name="Name.Space.*" writeTo="f3,f4" />
+ </x>
+ - messages from any class in the <font face="Courier New">Name.Space</font> namespace are written to both "<font face="Courier New">f3</font>" and "<font face="Courier New">f4</font>" targets regardless of their levels.
+ </li>
+ <li>
+ <x>
+ <logger name="Name.Space.*" minlevel="Debug" maxlevel="Error" final="true" />
+ </x>
+ - messages from any class in the <font face="Courier New">Name.Space</font> namespace whose level is
+ between <font face="Courier New">Debug</font> and <font face="Courier New">Error</font> (which makes it
+ <font face="Courier New">Debug,Info,Warn,Error</font>) are rejected (as there's no
+ <font face="Courier New">writeTo</font> clause)
+ and no futher rules are processed for them (because of the <font face="Courier New">final="true"</font> setting)
+ </li>
+ </ul>
+ <p>
+ In the simplest cases the entire logging configuration consists of a single <x><target/></x> and
+ a single <x><logger /></x> rule that routes messages to this target depending on their level.
+ As the application grows, adding more targets and rules is very simple.
+ </p>
+ <h4>Contextual information</h4>
+ <p>
+ One of NLog's strongest assets is the ability to use layouts. They include pieces of text surrounded by a pair
+ of "<b>${</b>" (dollar sign + left curly brace) and "<b>}</b>" (right curly brace). The markup denotes
+ "layout renderers" which can be used to insert pieces of <b>contextual information</b> into the text.
+ Layouts can be used in many places, for example they can control the format of information written on the
+ screen or sent to a file, but also to control the file names themselves. This is very powerful,
+ which we'll see in a moment.
+ </p>
+ <p>
+ Let's assume, that we want to augment each message written to the console with:
+ </p>
+ <ul>
+ <li>current date and time</li>
+ <li>name of the class and method that emitted the log message</li>
+ <li>log level</li>
+ <li>message text</li>
+ </ul>
+ <p>This is very easy:</p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="c" xsi:type="Console" layout="${longdate} ${callsite} ${level} ${message}" />
+ ]]>
+ </code>
+ <p>
+ We can make each messages for each logger go to a separate file, as in the following example:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="f" xsi:type="File" fileName="${logger}.txt" />
+ ]]>
+ </code>
+
+ <p>
+ Ay you can see the <font face="Courier New">${logger}</font> layout renderer was used
+ in the <font face="Courier New">fileName</font> attribute, which causes each log message
+ to be written to the file whose name includes the logger name. The above example will
+ create the following files:
+ </p>
+ <ul>
+ <li>Name.Space.Class1.txt</li>
+ <li>Name.Space.Class2.txt</li>
+ <li>Name.Space.Class3.txt</li>
+ <li>Other.Name.Space.Class1.txt</li>
+ <li>Other.Name.Space.Class2.txt</li>
+ <li>Other.Name.Space.Class3.txt</li>
+ <li>...</li>
+ </ul>>
+ <p>It's a frequent requirement to be able to keep log files for each day separate.
+ This is trivial, too, thanks to the ${shortdate} layout renderer:</p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="f" xsi:type="File" filename="${shortdate}.txt" />
+ ]]>
+ </code>
+ <p>
+ How about givin each employee their own log file? The ${windows-identity} layout renderer will do the trick:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="f" xsi:type="File" filename="${windows-identity:domain=false}.txt" />
+ ]]>
+ </code>
+ <p>
+ Thanks to this simple setting NLog will create a set of files named after our employees' logins:
+ </p>
+ <ol>
+ <li>Administrator.txt</li>
+ <li>MaryManager.txt</li>
+ <li>EdwardEmployee.txt</li>
+ <li>...</li>
+ </ol>
+ <p>
+ More complex cases are of course possible. The following sample demonstrates the way of creating
+ a distinct log file for each person per day. Log files for each day are stored in a separate directory:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="f" xsi:type="File" filename="${shortdate}/${windows-identity:domain=false}.txt" />
+ ]]>
+ </code>
+ <p>This creates the following files:</p>
+ <ol>
+ <li>2006-01-01/Administrator.txt</li>
+ <li>2006-01-01/MaryManager.txt</li>
+ <li>2006-01-01/EdwardEmployee.txt</li>
+ <li>2006-01-02/Administrator.txt</li>
+ <li>2006-01-02/MaryManager.txt</li>
+ <li>2006-01-02/EdwardEmployee.txt</li>
+ <li>...</li>
+ </ol>
+
+ <p>
+ NLog provides many predefined layout renderers. They are described on the
+ <a href="http://www.nlog-project.org/layoutrenderers.html">http://www.nlog-project.org/layoutrenderers.html</a> page.
+ It's very easy to create your own layout renderer. It just takes 15-20 lines of code and is described in the <a href="http://www.nlog-project.org/documentation.html">documentation</a>
+ section of the project website.
+ </p>
+
+ <h4>Include files </h4>
+ <p>
+ It's sometimes desired to split the configuration file into many smaller ones.
+ NLog provides an include file mechanism for that. To include an external file, you simply use
+ It's worth noting that the fileName attribute, just like most attributes in
+ NLog config file(s), may include dynamic values using the familiar
+ ${var} notation, so it's possible to include different files based on environmental properties.
+ The following configuration example demonstrates this, by loading file whose name is derived from
+ the name of the machine we're running on.
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <nlog>
+ ...
+ <include file="${basedir}/${machinename}.config" />
+ ...
+ </nlog>
+ ]]>
+ </code>
+ <p>
+ Variables let us write complex or repeatable expression (such as file names) in a concise manner.
+ To define a variable we use the <x><variable name="var" value="xxx" /></x> syntax.
+ Once defined, variables can be used as if they were layout renderers - by using ${var} syntax, as demonstrated in
+ the following example:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <nlog>
+ <variable name="logDirectory" value="${basedir}/logs/${shortdate}" />
+
+ <targets>
+ <target name="file1" xsi:type="File" filename="${logDirectory}/file1.txt" />
+ <target name="file2" xsi:type="File" filename="${logDirectory}/file2.txt" />
+ </targets>
+ </nlog>
+ ]]>
+ </code>
+
+ <h4>Automatic reconfiguration</h4>
+ <p>
+ The configuration file is read automatically at program startup. In a long running process (such as a Windows
+ service or an ASP.NET application) it's sometimes desirable to temporarily increase the log level without
+ stopping the application. NLog can monitor logging
+ configuration files and re-read them each time they are modified. To enable this mechanism, you simply set
+ <x><nlog autoReload="true" /></x> in your configuration file. Note that automatic reconfiguration
+ supports include files, so each time one of the files include is changed, the entire configuration gets reloaded.
+ </p>
+
+ <h4>Troubleshooting logging</h4>
+ <p>
+ Sometimes our application doesn't write anything to the log files, even though we have supposedly configured
+ logging properly. There can be many reasons for logs not being written. The most common problem are permissions,
+ usually in an ASP.NET process, where the aspnet_wp.exe or w3wp.exe process may not have write access to the directory
+ where we want to store logs.
+
+ NLog is designed to swallow run-time exceptions that may result from
+ logging. The following settings can change this behavior and/or
+ redirect these messages.
+ </p>
+ <ul>
+ <li>
+ <x>
+ <nlog throwExceptions="true" />
+ </x>- adding throwExceptions attribute in the config file causes NLog not to mask exceptions and pass them
+ to the calling application instead. This attribute is useful at deployment time to quickly locate any problems.
+ It's recommended to turn throwExceptions to "false" as soon as the application is properly configured to run,
+ so that any accidental logging problems won't crash the application.
+ </li>
+ <li>
+ <x>
+ <nlog internalLogFile="file.txt" />
+ </x>- adding internalLogFile cause NLog to write its internal debugging messages to the specified file.
+ This includes any exceptions that may be thrown during logging.
+ </li>
+ <li>
+ <x>
+ <nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" />
+ </x> - determines internal log level. The higher the level, the less verbose the internal log output.
+ </li>
+ <li>
+ <x>
+ <nlog internalLogToConsole="false|true" />
+ </x> - sends internal logging messages to the console.
+ </li>
+ <li>
+ <x>
+ <nlog internalLogToConsoleError="false|true" />
+ </x> - sends internal logging messages to the console error output (stderr).
+ </li>
+ </ul>
+
+ <h4>Asynchronous processing, wrapper and compound targets</h4>
+ <p>
+ NLog provides wrapper and compound targets which modify other targets' behaviour by adding features like:
+ </p>
+ <ul>
+ <li>asynchronous processing (wrapped target runs in a separate thread)</li>
+ <li>retry-on-error</li>
+ <li>load balancing (round-robin targets)</li>
+ <li>buffering</li>
+ <li>filtering</li>
+ <li>backup targets (failover)</li>
+ <li>and others described on <a href="http://www.nlog-project.org/targets.html">http://www.nlog-project.org/targets.html</a></li>
+ </ul>
+ <p>
+ To define a wrapper or compound target in the configuration file,
+ simply nest a target node within another target node. You can even wrap
+ a wrapper target. There are no limits on depth.
+ For example, to add asynchronous logging with retry-on-error functionality
+ add this to your configuration file:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <targets>
+ <target name="n" xsi:type="AsyncWrapper">
+ <target xsi:type="RetryingWrapper">
+ <target xsi:type="File" fileName="${file}.txt" />
+ </target>
+ </target>
+ </targets>
+ ]]>
+ </code>
+ <p>
+ Because asynchronous processing is a common scenario, NLog supports a shorthand notation
+ to enable it for all targets without the need to specify explicit wrappers. You simply
+ set <x><targets async="true" /></x> and all your targets will be wrapped with the AsyncWrapper target.
+ </p>
+
+ <h2>Programmatic configuration</h2>
+ <p>
+ In certain cases you may choose not to use configuration file, but to configure NLog using the provided API.
+ Full description of this feature is beyond the scope of this article, so let's just outline the steps
+ necessary to make it work. To configure NLog in code you need to:
+ </p>
+ <ol>
+ <li>Create a LoggingConfiguration object that will hold the configuration</li>
+ <li>Create one or more targets (objects of classes inheriting from Target)</li>
+ <li>Set the properties of the targets</li>
+ <li>Define logging rules through LoggingRule objects and add them to configuration's LoggingRules</li>
+ <li>Activate the configuration by assigning the configuration object to LogManager.Configuration</li>
+ </ol>
+ <p>This sample demonstrates the programmatic creation of two targets: one is a colored console and the other
+ is a file and rules that send messages to them for messages whose level is Debug or higher.
+ </p>
+ <code lang="C#">
+ <![CDATA[using NLog;
+using NLog.Targets;
+using NLog.Config;
+using NLog.Win32.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ // Step 1. Create configuration object
+
+ LoggingConfiguration config = new LoggingConfiguration();
+
+ // Step 2. Create targets and add them to the configuration
+
+ ColoredConsoleTarget consoleTarget = new ColoredConsoleTarget();
+ config.AddTarget("console", consoleTarget);
+
+ FileTarget fileTarget = new FileTarget();
+ config.AddTarget("file", fileTarget);
+
+ // Step 3. Set target properties
+
+ consoleTarget.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
+ fileTarget.FileName = "${basedir}/file.txt";
+ fileTarget.Layout = "${message}";
+
+ // Step 4. Define rules
+
+ LoggingRule rule1 = new LoggingRule("*", LogLevel.Debug, consoleTarget);
+ config.LoggingRules.Add(rule1);
+
+ LoggingRule rule2 = new LoggingRule("*", LogLevel.Debug, fileTarget);
+ config.LoggingRules.Add(rule2);
+
+ // Step 5. Activate the configuration
+
+ LogManager.Configuration = config;
+
+ // Example usage
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Trace("trace log message");
+ logger.Debug("debug log message");
+ logger.Info("info log message");
+ logger.Warn("warn log message");
+ logger.Error("error log message");
+ logger.Fatal("fatal log message");
+ }
+}]]>
+ </code>
+ <h2>What else is possible with NLog?</h2>
+ <p>
+ NLog supports some more logging scenarios, which couldn't be
+ fully described here. See the links below for more information:
+ </p>
+ <ul>
+ <li>
+ exception logging - <a href="http://sourceforge.net/mailarchive/forum.php?thread_id=6766833&forum_id=41984">http://sourceforge.net/mailarchive/forum.php?thread_id=6766833&forum_id=41984</a>
+ </li>
+ <li>
+ conditional expressions language - <a href="http://www.nlog-project.org/filters.html">http://www.nlog-project.org/conditions.html</a>
+ </li>
+ <li>
+ NLogViewer - real-time log viewer application (currently in pre-alpha stage) - <a href="http://viewer.nlog-project.org/">http://viewer.nlog-project.org/</a>
+ </li>
+ </ul>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/tutorial_old.xml b/web/tutorial_old.xml
new file mode 100644
index 0000000..f619ce6
--- /dev/null
+++ b/web/tutorial_old.xml
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" subid="tutorial">
+ <h1>Introduction to NLog</h1>
+
+ <h3>Basic concepts</h3>
+ <p>NLog is a log routing engine. It processes log messages that are output by the components of your program,
+ formats them according to your preference, filters them according to their level, source and content
+ and outputs them to one or more place based on a set of rules.</p>
+ <h5>Loggers and LogManager</h5>
+ <p>
+ To write a log message in your code you use an instance of a <code>Logger</code> which you acquire from
+ a <code>LogManager</code>. You can think of loggers as of log sources and targets as log sinks. Typically
+ there's one source for each class named after its full name including namespace, e.g.
+ <code>MyCompany.MyProject.NameSpace.ClassName</code> but you may invent your own naming schema as well.
+ </p>
+ <h5>Log levels</h5>
+ <p>
+ Each message that you output has a level which describes its importance.
+ There are 6 predefined logging levels. They are: <code>Trace, Debug, Info, Warn, Error, Fatal</code>. Unlike other logging frameworks
+ NLog <b>does NOT</b> support introducing more logging levels, but I believe that in this case "<i>less is more</i>".
+ </p>
+ <p>
+ The following table describes the allowed logging levels along with their recommended usage.
+ </p>
+ <div class="table">
+ <table>
+ <col width="10%" />
+ <col width="90%" />
+ <tr>
+ <th>Log Level</th>
+ <th>Meaning</th>
+ </tr>
+ <tr>
+ <td>Trace</td>
+ <td>Messages useful to programmer only, not normally enabled, even by the support team. This level can include high-volume messages like the dump of entire datasets, XML documents, detailed parameter information, etc.</td>
+ </tr>
+ <tr>
+ <td>Debug</td>
+ <td>Messages useful for debugging, not normally enabled. This level can include high-traffic messages like the ones you write at each method call.</td>
+ </tr>
+ <tr>
+ <td>Info</td>
+ <td>Normal informational messages. Typically low traffic information - like "user logged on", "user authenticated".</td>
+ </tr>
+ <tr>
+ <td>Warn</td>
+ <td>Warning messages.</td>
+ </tr>
+ <tr>
+ <td>Error</td>
+ <td>Error messages.</td>
+ </tr>
+ <tr>
+ <td>Fatal</td>
+ <td>Fatal error messages. You usually write just one such message - just before the application terminates.</td>
+ </tr>
+ </table>
+ </div>
+
+ <h5>Log routing table</h5>
+ <p>
+ A <i>routing table</i> is used to manage the log rules. It can be accessed either programmatically
+ or as an XML document either standalone or embedded in the application configuration file <code>App.config</code>.
+ </p>
+ <code lang="xml" src="examples/web/config6.nlog" />
+ <p>
+ The routing table is made up of the following main parts:
+ </p>
+ <ul>
+ <li><b>targets</b> (previously called "appenders") - which specify where log output will go</li>
+ <li><b>rules</b> - which describe the way log messages are routed to reach targets</li>
+ </ul>
+ <p>
+ Each <x><rule/></x> definition consists of a logger name pattern, level specification and target information. The meaning
+ is very simple: "<i>Each time a logger name matches the pattern and level matches the level specification, write the formatted
+ log message to the specified target</i>".
+ </p>
+ <p>
+ As you can see the routing table is quite clean and simple, but very powerful.
+ Some examples of what you can use with it include:
+ </p>
+ <ul>
+ <li>send single log message to one or more targets (for example: both to the console and a log file)</li>
+ <li>filter logging messages by their level</li>
+ <li>filter logging messages by their logger name using wildcards</li>
+ </ul>
+ <p>
+ It's also possible to use filters and final rules, and this is described below in advanced section.
+ </p>
+ <h5>Layouts and layout renderers</h5>
+ <p>
+ Layouts are one of the coolest features of NLog. They let you annotate log messages with environmental information like:
+ </p>
+ <ul>
+ <li>date and time in various formats</li>
+ <li>stack trace information</li>
+ <li>exception information</li>
+ <li>classic ASP and ASP.NET session, request and application objects</li>
+ <li>path information (such as appdomain base directory)</li>
+ <li>log event information (logger name, log level)</li>
+ <li>process and thread information</li>
+ <li>machine name information</li>
+ <li>diagnostic contexts</li>
+ <li>counters, guids, and more</li>
+ </ul>
+ <p>
+ Each target has a parameter called <code>layout</code> that describes the log output formatting. By default
+ it is:
+ </p>
+ <p>
+ <code>${longdate}|${level:uppercase=true}|${logger}|${message}</code>
+ </p>
+ <p>
+ so that each log line contains the data, log level, logger name and log message. This can be extended, for example,
+ to provide some particular value from ASP.NET session state, thread id and call site (class and name of the
+ invoking method):
+ </p>
+ <p>
+ <code>${longdate} ${level:uppercase=true} ${logger} ${aspnet-session:variable=UserName} ${threadid} ${callsite} ${message}</code>
+ </p>
+ <p>
+ Now, each logging message (a line in the output file) will contain all of the above useful information. Example of a real-life configuration that does just that and writes output to both a file and ASP.NET trace facility. Note how the file output is more detailed than ASP.NET trace output:
+ </p>
+ <code lang="xml" src="examples/web/config11.nlog" />
+ <p>
+ It's even possible to write each log message to a different file based on environmental properties.
+ For example, to write to a new file each day separated by the log level, just change <code>filename=""</code> to:
+ </p>
+ <p>
+ <code>filename="${basedir}/../logs/${date:format=yyyy-MM-dd}_${level}_log.txt"</code>
+ </p>
+ <p>
+ The resulting files will be named:
+ </p>
+ <ol>
+ <li><code>../logs/2005-05-29_Debug_log.txt</code></li>
+ <li><code>../logs/2005-05-29_Info_log.txt</code></li>
+ <li><code>../logs/2005-05-29_Warn_log.txt</code></li>
+ <li><code>../logs/2005-05-29_Error_log.txt</code></li>
+ <li><code>../logs/2005-05-29_Fatal_log.txt</code></li>
+ <li><code>../logs/2005-05-30_Debug_log.txt</code></li>
+ <li><code>../logs/2005-05-30_Info_log.txt</code></li>
+ <li><code>../logs/2005-05-30_Warn_log.txt</code></li>
+ <li><code>../logs/2005-05-30_Error_log.txt</code></li>
+ <li><code>../logs/2005-05-30_Fatal_log.txt</code></li>
+ <li>...</li>
+ </ol>
+ <p>You can probably see that the possibilities are endless. See the <link href="layoutrenderers">Layout Renderers</link> for more information.</p>
+ <h5>Logger usage</h5>
+ <p>Usage is simple. Just get an instance of a <code>Logger</code> from the <code>LogManager</code> and
+ write your messages to it like you do with <code>Console.WriteLine()</code>. To write a message at a particular
+ level use a method that's named after the level.</p>
+ <p>The following code example shows what's available:</p>
+
+ <code lang="C#" src="examples/web/tutorial.cs" />
+
+ <h3>Advanced concepts</h3>
+ <h5>Internal logging</h5>
+ <p>
+ There are cases where you need to debug your logging configuration. This is usually the case where you don't
+ get the expected log output. NLog provides a feature called internal logging. Internal logging
+ lets you write NLog-internal debugging messages to the console and/or a log file optionally specifying the
+ log level verbosity. Additionally you may want to tell NLog to throw exceptions on any error. This can
+ help you detect and fix configuration errors (mostly permission problems) easily.
+ </p>
+ <p>
+ The following options can be used in the configuration file to enable internal debugging:
+ </p>
+ <p>
+ <x><nlog internalLogToConsole="true | false" /></x><br/>
+ <x><nlog internalLogFile="filename" /></x><br/>
+ <x><nlog internalLogLevel="Trace | Debug | Info | Warn | Error | Fatal" /></x><br/>
+ <x><nlog throwExceptions="true | false" /></x><br/>
+ </p>
+ <p>
+ More information about internal logging can be found in the <link href="howto_troubleshoot">troubleshooting</link> section and in the <link href="config">configuration</link> section.
+ </p>
+ <h5>Include files</h5>
+ <p>
+ If you have many applications you may want to share their logging configurations. NLog provides <x><include /></x>
+ mechanism for that. TODO - write more.
+ </p>
+ <h5>Automatic config-file watching</h5>
+ <p>
+ There are cases where you need to modify the logging configuration at application runtime. Having to restart
+ your application in this case should be avoided especially on production servers.
+ NLog provides a convenient configuration attribute for this.
+ Just put the following in the configuration file:
+ </p>
+ <code lang="xml" src="examples/web/config12.nlog" />
+ <h5>Filters</h5>
+ <p>See the <link href="filters">Filter Reference</link> for more information. Tutorial will be added here soon.</p>
+ <h5>Final rules</h5>
+ <p>By default all NLog rules are additive, that is their effects add up. The rules are processed top-down
+ from the first rule to the last one. Sometimes you want to quit rule processing. That's what the <code>final</code> attribute
+ is used for. [TODO - more to be written].
+ </p>
+ <!--
+ <h5>Log processing detailed</h5>
+ <p>The following picture describes log processing. </p>
+ <img style="border: 1px solid #ffe0e0" src="nlog_routing.png" />
+ <p/>
+ -->
+</content>
diff --git a/web/visualstudio.xml b/web/visualstudio.xml
new file mode 100644
index 0000000..89242cc
--- /dev/null
+++ b/web/visualstudio.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <h3>Visual Studio Integration</h3>
+ <p>
+ NLog integrates with Visual Studio 2005 (including Visual C# and Visual Basic.NET Express Editions).
+ Integration with Visual Studio.NET 2002 and 2003 is also supported, but not all features are available.
+ Click on one of the following features for an example:
+ </p>
+ <ol>
+ <li><a href="#intellisense">Intellisense(TM)</a></li>
+ <li><a href="#addreference">Integration with Add/Reference dialog</a></li>
+ <li><a href="#itemtemplates">New Item Templates</a></li>
+ <li><a href="#codesnippets">Code Snippets</a></li>
+ </ol>
+
+ <a name="intellisense" />
+ <h5>Intellisense(TM)</h5>
+ <p>
+ NLog supports Intellisense when editing XML configuration files (both App.config-style, and stand-alone).
+ All you need to do is add two namespace declarations to the <x><nlog /></x> tag:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <!-- configuration goes here -->
+</nlog>
+ ]]>
+ </code>
+ <p>
+ The other change necessary is turning <x><target type="TypeName" /></x> into <x><target xsi:type="TypeName" /></x>. Once you do this,
+ you really good support for Intellisense and config file validation in Visual Studio as demonstrated
+ in <a href="http://www.nlog-project.org/demos/NLogDemo1.html">this movie</a> (22 MB Flash - broadband connection recommended).
+ </p>
+
+ <a name="addreference" />
+ <h5>Integration with Add/Reference dialog</h5>
+ <p>
+ NLog Setup registers the appropriate <i>AssemblyFolders</i> entry in registry so that Visual Studio is able to
+ locate the *.dll files and present them in Add Reference dialog. This is supported in all Visual Studio versions.
+ </p>
+ <img src="visualstudio_addreference.gif" />
+ <a name="itemtemplates" />
+ <h5>New Item Templates</h5>
+ <p>
+ NLog comes with 3 sample configuration files that can be quickly added to you project through Add New Item dialog. They are:
+ <ul>
+ <li>configuration file that defines one <a href="targets.html">File Target</a> (typical)</li>
+ <li>configuration file that defines one <a href="targets.html">Console Target</a></li>
+ <li>empty configuration file</li>
+ </ul>
+ </p>
+ <p>
+ <b style="color:red">Please note that you need to change "Copy To Output Directory" option on the NLog.config to "Copy Always"</b>
+ "New Item" templates are only supported with Visual Studio 2005 (including Express Editions).
+ </p>
+
+ <img src="visualstudio_addnewitem.gif" />
+
+ <a name="codesnippets" />
+ <h5>Code Snippets</h5>
+ <p>
+ NLog installs a Visual Studio 2005 Code Snippet called "<c>nlogger</c>" that can be used to quickly declare a logger instance. It inserts the following
+ piece of text:
+ </p>
+ <code lang="C#">
+ private static Logger logger = LogManager.GetCurrentClassLogger();
+ </code>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/visualstudio_addnewitem.gif b/web/visualstudio_addnewitem.gif
new file mode 100644
index 0000000..4a6c97a
Binary files /dev/null and b/web/visualstudio_addnewitem.gif differ
diff --git a/web/visualstudio_addreference.gif b/web/visualstudio_addreference.gif
new file mode 100644
index 0000000..a74ce13
Binary files /dev/null and b/web/visualstudio_addreference.gif differ
diff --git a/web/web.menu b/web/web.menu
new file mode 100644
index 0000000..db12036
--- /dev/null
+++ b/web/web.menu
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<common>
+ <navigation>
+ <nav href="introduction" label="Introduction" />
+ <nav href="download" label="Download" />
+ <nav href="documentation" label="Documentation" />
+ <nav href="faq" label="FAQ" />
+ <nav href="http://www.nabble.com/NLog-Forum-f6167.html" noext="true" label="Forum" />
+ <nav href="http://trac.nlog-project.org/nlog/" noext="true" label="Issue Tracker" />
+ <nav href="mailinglists" label="Mailing Lists" />
+ </navigation>
+</common>
diff --git a/web/website.xml b/web/website.xml
new file mode 100644
index 0000000..6bcd114
--- /dev/null
+++ b/web/website.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="website">
+ <h1>NLog website</h1>
+ <p>NLog website is located <a href="http://www.nlog-project.org/">here</a>. To report a bug, use the TRAC interface available <a href="http://trac.sav.net/nlog">here</a>.</p>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/wprowadzenie.xml b/web/wprowadzenie.xml
new file mode 100644
index 0000000..fdab6f9
--- /dev/null
+++ b/web/wprowadzenie.xml
@@ -0,0 +1,906 @@
+<?xml version="1.0" encoding="windows-1250" ?>
+<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
+<content lang="en" id="documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <h2>Wprowadzenie do ledzenia aplikacji przy pomocy bibliteki NLog</h2>
+ <p>Autor: Jaros³aw Kowalski <<a href="mailto:jaak at jkowalski.net">jaak at jkowalski.net</a>></p>
+ <div style="margin-left: 1cm; margin-right: 1cm">
+ <font color="#006400">
+ <i>
+ Dawno, dawno temu, kiedy na wiecie nie by³o jeszcze debugerów, a aplikacje by³y w wiêkszoci oparte o tekstow¹ konsolê, programici umieszczali w nich instrukcje <a href="http://www.cplusplus.com/ref/cstdio/printf.html">printf</a>() wypisuj¹ce komunikaty diagnostyczne na ekran. Kilka lat póniej wiat poszed³ znacznie do przodu i instrukcje printf() zosta³y zast¹pione przez Console.WriteLine()...
+ </i>
+ </font>
+ </div>
+ <p>
+ Zapewne ka¿dy z nas napisa³ kiedy kod podobny do poni¿szego:
+ </p>
+ <code lang="C#">
+ <![CDATA[
+ static void Main()
+ {
+ Console.WriteLine("Program SuperApp zosta³ uruchomiony...");
+ DoSomething(0);
+ Console.WriteLine("Program SuperApp koñczy dzia³anie");
+ }]]>
+ </code>
+
+ <p>Instrukcje Console.WriteLine() pe³ni¹ tu rolê instrukcji ledz¹cych, które informuj¹
+ o dzia³aniu programu. Na ich podstawie mo¿emy siê zorientowaæ, czy program
+ dzia³a poprawnie lub te¿ czy siê nie zawiesi³. Zwykle po jako-takim przetestowaniu instrukcje Console.WriteLine()
+ s¹ wy³¹czane, aby nie spowalniaæ dzia³ania programu.
+ Czêsto jednak, po pewnym czasie przychodzi potrzeba ponownego w³¹czenia ledzenia w aplikacji,
+ dlatego te¿ instrukcje ledz¹ce w kodzie zwykle zamieniamy na komentarze zamiast fizycznie je usuwaæ.
+ </p>
+ <p>
+ Po kilku iteracjach dochodzimy zwykle do wniosku, ¿e obs³uga ledzenia naszej aplikacji,
+ by³aby du¿o bardziej u¿yteczna, gdyby mo¿liwe by³o:
+ </p>
+ <ul>
+ <li>
+ sterowanie poziomem szczegó³owoci informacji diagnostycznych (np. wywietlanie wy³¹cznie b³êdów i ostrze¿eñ lub bardzo dok³adne informacje przydatne do debugowania)
+ </li>
+ <li>w³¹czanie i wy³¹czanie ledzenia dla poszczególnych klas i bibliotek w trakcie dzia³ania programu, bez jego zatrzymywania</li>
+ <li>
+ zapisywanie komunikatów do pliku, systemowego dziennika zdarzeñ, do³¹czonego debugera, itp.
+ </li>
+ <li>wysy³anie szczególnie wa¿nych komunikatów mailem lub zapisywanie ich w bazie danych</li>
+ <li>i wiele innych</li>
+ </ul>
+ <p>
+ Wydaje siê, ¿e w dobie graficznych narzêdzi do debugowania u¿ytecznoæ rozwi¹zañ opartych
+ na ledzeniu jest ma³a. Czêsto jednak s¹ to jedyne dostêpne narzêdzia, które musz¹ nam
+ wystarczyæ np. do zlokalizowania przyczyny b³êdu w krytycznym systemie dzia³aj¹cym na
+ serwerze, którego nie mo¿na wy³¹czyæ nawet na chwilê.
+ </p>
+
+ <h2>Czym jest NLog?</h2>
+ <p>
+ NLog <a href="http://www.nlog-project.org/">(http://www.nlog-project.org)</a> jest
+ bibliotek¹ na platformie .NET, która umo¿liwia ³atwe wzbogacenie naszej
+ aplikacji o obs³ugê ledzenia, realizuj¹c¹ wymagania opisane powy¿ej,
+ a tak¿e du¿o wiêcej.
+ </p>
+ <p>
+ Najprociej rzecz ujmuj¹c NLog umo¿liwia tworzenie <b>regu³ </b>steruj¹cych przep³ywem
+ komunikatów diagnostycznych od <b>ród³a</b> do <b>celu</b>, którym mo¿e byæ:
+ </p>
+ <ul>
+ <li>plik</li>
+ <li>konsola tekstowa</li>
+ <li>wiadomoæ email</li>
+ <li>baza danych</li>
+ <li>inny komputer w sieci (protokó³ TCP/UDP)</li>
+ <li>kolejka komunikatów MSMQ</li>
+ <li>systemowy dziennik zdarzeñ (Event Log)</li>
+ <li>
+ i inne opisane na stronie <a href="http://www.nlog-project.org/targets.html">http://www.nlog-project.org/targets.html</a>
+ </li>
+ </ul>
+ <p>
+ Dodatkowo, ka¿dy komunikat diagnostyczny mo¿e byæ wzbogacony o <b>informacje kontekstowe</b>,
+ które razem z nim zostan¹ przes³ane do celu. Mog¹ to byæ:
+ </p>
+ <ul>
+ <li>bie¿¹ca data i godzina (w ró¿nych formatach)</li>
+ <li>poziom wa¿noci</li>
+ <li>nazwa ród³a</li>
+ <li>informacje o metodzie, która wyemitowa³a komunikat diagnostyczny</li>
+ <li>zawartoci zmiennych rodowiskowych</li>
+ <li>informacje o wyj¹tku</li>
+ <li>nazwa maszyny, procesu i w¹tku, który emituje komunikat</li>
+ <li>
+ i wiele innych opisanych na stronie <a href="http://www.nlog-project.org/layoutrenderers.html">http://www.nlog-project.org/layoutrenderers.html</a>
+ </li>
+ </ul>
+ <p>
+ Ka¿dy komunikat diagnostyczny ma swój poziom (log level). Wspierane s¹ nastêpuj¹ce poziomy
+ </p>
+ <ul>
+ <li>
+ <b>Trace </b>- Szczegó³owe komunikaty diagnostyczne o potencjalnie du¿ej czêstotliwoci i objêtoci
+ </li>
+ <li>
+ <b>Debug </b>-Komunikaty diagnostyczne o niewielkiej czêstotliwoci i ma³ej objêtoci
+ </li>
+ <li>
+ <b>Info </b>- Komunikaty informacyjne, zwykle niezbyt czêste
+ </li>
+ <li>
+ <b>Warn </b>- Ostrze¿enia nie powoduj¹ce b³êdnego dzia³ania programu
+ </li>
+ <li>
+ <b>Error </b>- B³êdy, które objawiaj¹ siê widocznym dla u¿ytkownika komunikatem
+ </li>
+ <li>
+ <b>Fatal </b>- B³êdy krytyczne, po których aplikacja zwykle koñczy swoje dzia³anie
+ </li>
+ </ul>
+ <p>
+ NLog jest rozwi¹zaniem open source dostêpnym za darmo na licencji BSD.
+ Najnowsz¹ wersjê biblioteki mo¿na zawsze pobraæ pod adresem
+ <a href="http://www.nlog-project.org/download.html">http://www.nlog-project.org/download.html</a>.
+ Dostêpny jest graficzny instalator, dziêki któremu mo¿na szybko i ³atwo zainstalowaæ NLoga w wybranym
+ miejscu, jak równie¿ (w najnowszej wersji), integracja z Visual Studio 2005 udostêpniaj¹ca:
+ </p>
+ <ul>
+ <li>wybór biblioteki NLog.dll z okna <code>Add Reference...</code></li>
+ <li>wsparcie dla kontekstowego podpowiadania sk³adni - Intellisense podczas edycji plików konfiguracyjnych</li>
+ <li>szablony plików konfiguracyjnych</li>
+ <li>code snippet</li>
+ </ul>
+
+ <h2>Pierwsza aplikacja wykorzystuj¹ca NLoga</h2>
+ <p>
+ Na pocz¹tek przyjrzyjmy siê, jak wygl¹da tworzenie aplikacji wykorzystuj¹cej NLog
+ przy u¿yciu Visual Studio 2005.
+ Przeanalizujemy 2 przyk³ady - jeden najprostszy, drugi bardziej skomplikowany,
+ które pokazuj¹ jak ³atwo jest sterowaæ konfiguracj¹ logowania.
+ </p>
+ <p>
+ Zaczynamy od utworzenia projektu w Visual Studio i dodania w nim pliku konfiguracyjnego NLoga.
+ Bêdziemy siê pos³ugiwaæ jêzykiem C#, ale NLog równie dobrze obs³uguje VB.NET i inne
+ jêzyki na platformie .NET. Instalator NLoga dodaje do okna "Add New Item..." kilka nowych opcji
+ pozwalaj¹cych nam na "szybki start". Dodajmy wiêc do projektu pusty plik konfiguracyjny NLoga
+ (Empty NLog Configuration File).
+ </p>
+ <img src="introduction_addnewitem.gif" />
+ <p>
+ Zauwa¿my, ¿e automatycznie zosta³a dodana referencja do biblioteki NLog i w projekcie pojawi³
+ siê plik o nazwie NLog.config o poni¿szej treci:
+ </p>
+
+ <code lang="XML">
+ <![CDATA[<?xml version="1.0" encoding="utf-8" ?>
+ <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ </targets>
+
+ <rules>
+ </rules>
+ </nlog>
+ ]]>
+ </code>
+
+ <p>W oknie w³aciwoci dla tego pliku nale¿y zaznaczyæ opcjê "Copy To Output Directory":</p>
+ <img src="introduction_copytooutput.gif" />
+
+ <p>
+ W sekcji <x>
+ <targets />
+ </x> dodajmy nastêpuj¹cy wpis definiuj¹cy wyjcie na konsolê i format tego wyjcia:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <targets>
+ <target name="console" xsi:type="Console" layout="${longdate}|${level}|${message}" />
+ </targets>
+ ]]>
+ </code>
+ <p>
+ Zauwa¿my, ¿e po Visual Studio podpowie nam dostêpne nazwy elementów i ich atrybutów, a po wpisaniu
+ <b>xsi:</b> uzyskamy listê dostêpnych celów logowania.
+ </p>
+ <img src="introduction_target_intellisense.gif" />
+
+ <p>
+ W sekcji <x>
+ <rules />
+ </x> dodajmy regu³ê kieruj¹c¹ komunikaty na poziomie Debug lub wy¿szym na konsolê.
+ </p>
+
+ <code lang="XML" escaped="true">
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="console" />
+ </rules>
+ </code>
+
+ <p>
+ Aby wys³aæ komunikat diagnostyczny pos³ugujemy siê obiektem klasy Logger, który udostêpnia metody o nazwach
+ odpowiadaj¹cych poziomom wa¿noci komunikatu. Obiekty Logger tworzymy za porednictwem klasy LogManager,
+ najwygodniej jest w tym celu wywo³aæ metodê LogManager.GetCurrentClassLogger(), która tworzy ród³o o takiej samej
+ nazwie jak bie¿¹ca klasa.
+ </p>
+ <p>
+ Zmodyfikujmy wygenerowany plik C# dodaj¹c na pocz¹tku polecenie using NLog, a w treci klasy instrukcjê tworzenia
+ obiektu Logger i wypisanie przyk³adowego komunikatu:
+ </p>
+
+ <code lang="C#">
+ <![CDATA[
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+ using NLog;
+
+ namespace NLogExample
+ {
+ class Program
+ {
+ private static Logger logger = LogManager.GetCurrentClassLogger();
+
+ static void Main(string[] args)
+ {
+ logger.Debug("Hello World!");
+ }
+ }
+ }
+ ]]>
+ </code>
+ <p>
+ Wynikiem dzia³ania programu jest wypisana na konsoli tekstowej bie¿¹ca data, poziom logowania
+ (<font face="Courier New">Debug</font>) i komunikat <font face="Courier New">Hello World</font>.
+ </p>
+
+ <p>
+ Spróbujmy przeledziæ teraz poszczególne etapy przetwarzania powy¿szego komunikatu diagnostycznego:
+ </p>
+ <ol>
+ <li>
+ Metoda <a href="http://www.nlog-project.org/help/NLog.LogManager.GetCurrentClassLogger.html">LogManager.GetCurrentClassLogger();</a>
+ tworzy obiekt klasy <a href="http://www.nlog-project.org/help/NLog.Logger.html">Logger</a> reprezentuj¹cy <b>ród³o</b>
+ logowania powi¹zane z bie¿¹c¹ klas¹.
+ </li>
+ <li>
+ Wywo³anie metody Debug() na tym obiekcie powoduje wys³anie zadanego komunikatu za
+ porednictwem wskazanego ród³a z poziomem logowania Debug
+ </li>
+ <li>
+ Poniewa¿ poziom logowania i ród³o odpowiadaj¹ zdefiniowanej regule,
+ komunikat jest formatowany zgodnie z wartoci¹ parametru layout elementu
+ <x>
+ <target />
+ </x> i wysy³any na konsolê.
+ </li>
+ </ol>
+ <h4>
+ Bardziej skomplikowana konfiguracja logowania
+ </h4>
+ <p>
+ Za³ó¿my, ¿e oprócz wypisywania na konsolê, chcemy jednoczenie zapisywaæ nasze komunikaty do pliku testowego i
+ rejestrowaæ informacje o bie¿¹cym stosie wywo³añ, czyli nazwy metod. Zdefiniujmy drugi cel logowania typu plikowego i skierujmy wszystkie komunikaty do niego. W³¹czmy te¿ poziom Trace.
+ Wymaga to jedynie dodania nowego elementu <x>
+ <target />
+ </x> typu File, modyfikacji regu³y <x>
+ <logger />
+ </x>
+ a tak¿e zmodyfikowania parametru layout.
+ </p>
+ <code lang="XML">
+ <![CDATA[<?xml version="1.0" encoding="utf-8" ?>
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <targets>
+ <target name="console" xsi:type="ColoredConsole" layout="${date:format=HH\:mm\:ss}|${level}|${stacktrace}|${message}" />
+ <target name="file" xsi:type="File" fileName="${basedir}/file.txt" layout="${stacktrace} ${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Trace" writeTo="console,file" />
+ </rules>
+</nlog>
+ ]]>
+ </code>
+
+
+ <p>
+ Wypiszmy tak¿e nieco wiêcej komunikatów na ró¿nych poziomach logowania. Wprowadmy te¿
+ kilka dodatkowych metod, tak aby zaobserwowaæ lad stosu:
+ </p>
+ <code lang="C#">
+ <![CDATA[
+ static void C()
+ {
+ logger.Info("Info CCC");
+ }
+ static void B()
+ {
+ logger.Trace("Trace BBB");
+ logger.Debug("Debug BBB");
+ logger.Info("Info BBB");
+ C();
+ logger.Warn("Warn BBB");
+ logger.Error("Error BBB");
+ logger.Fatal("Fatal BBB");
+ }
+ static void A()
+ {
+ logger.Trace("Trace AAA");
+ logger.Debug("Debug AAA");
+ logger.Info("Info AAA");
+ B();
+ logger.Warn("Warn AAA");
+ logger.Error("Error AAA");
+ logger.Fatal("Fatal AAA");
+ }
+ static void Main(string[] args)
+ {
+ logger.Trace("Komunikat techniczny na poziomie Trace");
+ logger.Debug("Komunikat techniczny na poziomie Debug");
+ logger.Info("Komunikat informacyjny na poziomie Info");
+ A();
+ logger.Warn("Komunikat-ostrze¿enie na poziomie Warn");
+ logger.Error("Komunikat o b³êdzie na poziomie Error");
+ logger.Fatal("Komunikat o b³êdzie krytycznym na poziomie Fatal");
+ }
+ ]]>
+ </code>
+ <p>
+ Uruchomienie programu spowoduje wypisanie na do pliku file.txt nastêpuj¹cych informacji:
+ </p>
+ <code lang="C#">
+ <![CDATA[
+Program.Main Komunikat techniczny na poziomie Trace
+Program.Main Komunikat techniczny na poziomie Debug
+Program.Main Komunikat informacyjny na poziomie Info
+Program.Main => Program.A Trace AAA
+Program.Main => Program.A Debug AAA
+Program.Main => Program.A Info AAA
+Program.Main => Program.A => Program.B Trace BBB
+Program.Main => Program.A => Program.B Debug BBB
+Program.Main => Program.A => Program.B Info BBB
+Program.A => Program.B => Program.C Info CCC
+Program.Main => Program.A => Program.B Warn BBB
+Program.Main => Program.A => Program.B Error BBB
+Program.Main => Program.A => Program.B Fatal BBB
+Program.Main => Program.A Warn AAA
+Program.Main => Program.A Error AAA
+Program.Main => Program.A Fatal AAA
+Program.Main Komunikat-ostrze¿enie na poziomie Warn
+Program.Main Komunikat o b³êdzie na poziomie Error
+Program.Main Komunikat o b³êdzie krytycznym na poziomie Fatal
+]]>
+ </code>
+ <p>W tym samym czasie konsolê wypisana zostanie wiadomoæ w innym formacie:</p>
+ <img src="introduction_coloredconsole.gif" />
+ <p>
+ Za³ó¿my, ¿e chcemy do pliku zapisywaæ wszystkie informacje, a na konsolê jedynie te najistotniejsze
+ (na poziomie <b>Info</b> lub wy¿szym). Nic prostszego, wystarczy jedynie zmieniæ sekcjê regu³:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <rules>
+ <logger name="*" minlevel="Info" writeTo="console" />
+ <logger name="*" minlevel="Trace" writeTo="file" />
+ </rules>
+ ]]>
+ </code>
+ <p>
+ Po uruchomieniu programu oka¿e siê, ¿e komunikaty na poziomie Trace i Debug s¹ zawarte wy³¹cznie w pliku,
+ podczas gdy nie widzimy ich na konsoli.
+ </p>
+ <h2>Konfiguracja logowania</h2>
+ <p>
+ Czas teraz, aby odpowiedzieæ na pytanie: jak to siê sta³o, ¿e NLog automatycznie odczyta³ poprawn¹ konfiguracjê?
+ Otó¿, w odró¿nieniu od innych narzêdzi tego typu, NLog stara siê maksymalnie u³atwiæ konfiguracjê, stosuj¹c rozmaite
+ zachowania domylne. NLog szuka pliku konfiguracyjnego w nastêpuj¹cych standardowych lokalizacjach:
+ </p>
+ <ul>
+ <li>
+ standardowy plik konfiguracyjny programu (zwykle <font face="Courier New">aplikacja.exe.config)</font>
+ </li>
+ <li>
+ plik <font face="Courier New">aplikacja.exe.nlog</font> w katalogu aplikacji
+ </li>
+ <li>
+ plik <font face="Courier New">NLog.config</font> w katalogu aplikacji
+ </li>
+ <li>
+ plik <font face="Courier New">NLog.dll.nlog</font> w katalogu, w którym znajduje siê plik <font face="Courier New">NLog.dll</font>
+ </li>
+ <li>
+ jeli istnieje zmienna rodowiskowa <font face="Courier New">NLOG_GLOBAL_CONFIG_FILE</font>, sprawdzane jest miejsce wskazywane przez tê zmienn¹<font face="Courier New"></font>
+ </li>
+ </ul>
+ <p>
+ W przypadku aplikacji ASP.NET przeszukiwane s¹:
+ </p>
+ <ul>
+ <li>
+ standardowy plik konfiguracyjny <font face="Courier New">web.config</font>
+ </li>
+ <li>
+ plik <font face="Courier New">web.nlog</font> w katalogu aplikacji (obok <font face="Courier New">web.config</font>)
+ </li>
+ <li>
+ plik <font face="Courier New">NLog.config</font> w katalogu aplikacji
+ </li>
+ <li>
+ plik <font face="Courier New">NLog.dll.nlog</font> w katalogu, w którym znajduje siê plik <font face="Courier New">NLog.dll </font>(zwykle "bin")
+ </li>
+ <li>
+ jeli istnieje zmienna rodowiskowa <font face="Courier New">NLOG_GLOBAL_CONFIG_FILE</font>, sprawdzane jest miejsce wskazywane przez tê zmienn¹
+ </li>
+ </ul>
+ <p>
+ W rodowisku .NET Compact Framework nie wystêpuje pojêcie pliku konfiguracyjnego aplikacji (*.exe.config) ani zmienne rodowiskowe, dlatego sprawdzane s¹ tylko trzy lokalizacje:
+ </p>
+ <ul>
+ <li>
+ plik <font face="Courier New">aplikacja.exe.nlog</font> w katalogu aplikacji
+ </li>
+ <li>
+ plik <font face="Courier New">NLog.config</font> w katalogu aplikacji
+ </li>
+ <li>
+ plik <font face="Courier New">NLog.dll.nlog</font> w katalogu, w którym znajduje siê plik <font face="Courier New">NLog.dll</font>
+ </li>
+ </ul>
+ <p>
+ Przeszukiwany zestaw plików zosta³ tak dobrany, aby umo¿liwiæ automatyczn¹ konfiguracjê we wszystkich typowych trybach
+ dzia³ania aplikacji bez koniecznoci wykonywania ¿adnych dodatkowych czynnoci.
+ </p>
+ <h4>Format pliku konfiguracyjnego</h4>
+ <p>
+ Dostêpne s¹ 2 formaty konfiguracji NLoga:
+ </p>
+ <ul>
+ <li>osadzona wewn¹trz pliku konfiguracyjnego aplikacji</li>
+ <li>uproszczona</li>
+ </ul>
+ <p>
+ W pierwszym przypadku pos³ugujemy siê standardowym mechanizmem sekcji konfiguracyjnych, dziêki którym nasz plik wygl¹da
+ jak poni¿ej:
+ </p>
+ <code lang="XML">
+ <![CDATA[<?xml version="1.0" encoding="utf-8" ?>
+ <configuration>
+ <configSections>
+ <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
+ </configSections>
+ <nlog>
+ </nlog>
+ </configuration>
+ ]]>
+ </code>
+ <p>
+ Format uproszczony wystêpuje w przypadku plików z rozszerzeniem *.nlog oraz NLog.config i
+ sk³ada siê bezporednio z pliku XML zawieraj¹cego element <x>
+ <nlog />
+ </x> jako korzeñ.
+ U¿ycie przestrzeni nazw jest opcjonalne, ale umo¿liwia dzia³anie mechanizmu Intellisense w Visual Studio.
+ </p>
+ <code lang="XML">
+ <![CDATA[<?xml version="1.0" encoding="utf-8" ?>
+ <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ </nlog>
+ ]]>
+ </code>
+ <h4>Elementy konfiguracyjne</h4>
+ <p>
+ Wewn¹trz elementu <x>
+ <nlog />
+ </x> mo¿na u¿ywaæ nastêpuj¹cych elementów, z czego zwykle u¿ywane s¹ dwa pierwsze elementy z poni¿szej listy.
+ </p>
+ <ul>
+ <li>
+ <x><targets /></x> - definiuje cele logowania
+ </li>
+ <li>
+ <x><rules /></x> - definiuje regu³y kierowania komunikatów diagnostycznych
+ </li>
+ <li>
+ <x><extensions /></x> - ³aduje rozszerzenia NLoga z pliku *.dll
+ </li>
+ <li>
+ <x><include /></x> - do³¹cza zewnêtrzny plik konfiguracyjny
+ </li>
+ <li>
+ <x><variable /></x> - ustawia wartoæ zmiennej konfiguracyjnej
+ </li>
+ </ul>
+ <h4>Cele</h4>
+ <p>
+ Wewn¹trz sekcji <x>
+ <targets />
+ </x> definiujemy cele logowania,
+ które s¹ reprezentowane przez elementy <x>
+ <target />
+ </x>
+ Ka¿dy cel musi mieæ okrelone 2 atrybuty:
+ </p>
+ <ul>
+ <li>
+ <font face="Courier New">name</font> - nazwa
+ </li>
+ <li>
+ <font face="Courier New">type</font> - typ celu (w przypadku korzystania z przestrzeni nazw xsi:type)
+ </li>
+ </ul>
+ <p>
+ Dodatkowo cele zwykle akceptuj¹ inne parametry - wp³ywaj¹ce na sposób zapisywania informacji diagnostycznej.
+ Dla ka¿dego celu zestaw parametrów jest inny - s¹ one szczegó³owo opisane na stronie projektu
+ jak równie¿ dostêpne kontekstowo w trakcie edycji pliku konfiguracyjnego dziêki Intellisense.
+ </p>
+ <p>
+ Przyk³adowo - cel typu "File" (plik) akceptuje parametr "fileName" definiuj¹cy nazwê pliku a cel typu "Console"
+ akceptuje parametr "error" okrelaj¹cy czy komunikaty diagnostyczne maj¹ byæ wypisywane na standardowe wyjcie
+ (stdout) czy na standardowe wyjcie dla b³êdów (stderr).
+ </p>
+ <p>
+ NLog udostêpnia wiele predefiniowanych celów. S¹ one opisane na stronie projektu. Bardzo ³atwo jest tak¿e utworzyæ
+ swój w³asny cel - wymaga to zaledwie kilkunastu wierszy kodu i jest opisane
+ w <a href="http://www.nlog-project.org/documentation.html">dokumentacji projektu</a>.
+ </p>
+ <h4>Regu³y</h4>
+ <p>
+ Regu³y sterowania logowaniem definiujemy w sekcji <x>
+ <rules />
+ </x>. Jest to prosta tabela routingu, gdzie w
+ ka¿dej regule na podstawie nazwy ród³a i poziomu logowania mo¿emy skierowaæ wynik do okrelonego celu lub
+ listy celów. Dodatkowo mo¿emy zdecydowaæ czy po zapisaniu maj¹ byæ uwzglêdniane dalsze regu³y czy te¿ zakoñczyæ
+ ich przetwarzanie.
+ </p>
+ <p>
+ Ka¿dy wpis w tabeli routingu ma formê elementu <x>
+ <logger />
+ </x>, który przyjmuje nastêpuj¹ce atrybuty:
+ </p>
+ <ul>
+ <li>
+ <font face="Courier New">name</font> - nazwa ród³a (mo¿e zawieraæ symbole wieloznaczne * na pocz¹tku i/lub na koñcu)
+ </li>
+ <li>
+ <font face="Courier New">minlevel</font> - minimalny poziom logowania wymagany do tego aby regu³a zadzia³a³a
+ </li>
+ <li>
+ <font face="Courier New">maxlevel</font> - maksymalny poziom logowania wymagany do tego aby regu³a zadzia³a³a
+ </li>
+ <li>
+ <font face="Courier New">level</font> - poziom logowania (pojedynczy) wymagany do tego aby regu³a zadzia³a³a
+ </li>
+ <li>
+ <font face="Courier New">levels </font>- lista poziomów logowania, które aktywuj¹ regu³ê
+ </li>
+ <li>
+ <font face="Courier New">writeTo</font> - lista nazw celów, do których zapisaæ komunikat
+ </li>
+ <li>
+ <font face="Courier New">final</font> - czy regu³a jest koñcz¹ca. Jeli tak, po jej zadzia³aniu nie s¹ przetwarzane ¿adne dalsze regu³y
+ </li>
+ </ul>
+ <p>
+ Poni¿ej kilka przyk³adów:
+ </p>
+ <ul>
+ <li>
+ <x>
+ <logger name="Name.Space.Klasa1" minlevel="Debug" writeTo="f1" />
+ </x> - komunikaty z klasy <font face="Courier New">Klasa1</font> w przestrzeni nazw <font face="Courier New">Name.Space</font> na poziomie <font face="Courier New">Debug</font> lub wy¿szym s¹ zapisywane do celu "<font face="Courier New">f</font>1"
+ </li>
+ <li>
+ <x>
+ <logger name="Name.Space.Klasa1" levels="Debug,Error" writeTo="f1" />
+ </x> - komunikaty z klasy <font face="Courier New">Klasa1</font> w przestrzeni nazw <font face="Courier New">Name.Space</font> na poziomach <font face="Courier New">Debug</font> i Error zapisywane do celu "<font face="Courier New">f2</font>"
+ </li>
+ <li>
+ <x>
+ <logger
+ name="Name.Space.*" writeTo="f3,f4" />
+ </x>
+ - komunikaty ze wszystkich klas w przestrzeni nazw <font face="Courier New">Name.Space</font> niezale¿nie od ich poziomu s¹ zapisywane do celów "<font face="Courier New">f3</font>" i "<font face="Courier New">f4</font>"
+ </li>
+ <li>
+ <x>
+ <logger
+ name="Name.Space.*" minlevel="Debug" maxlevel="Error" final="true" />
+ </x>
+ - komunikaty ze wszystkich klas w przestrzeni nazw <font face="Courier New">Name.Space</font> na poziomie wiêkszym ni¿ <font face="Courier New">Debug</font> i mniejszym ni¿ <font face="Courier New">Error</font> (czyli <font face="Courier New">Debug,Info,Warn,Error</font>) s¹ odrzucane (poniewa¿ nie podano klauzuli <font face="Courier New">writeTo</font>) i nie s¹ przetwarzane dla nich kolejne regu³y (ze wzglêdu na <font face="Courier New">final="true"</font>)
+ </li>
+ </ul>
+ <p>
+ W najprostszych aplikacjach konfiguracja logowania wygl¹da zwykle tak, ¿e mamy jeden cel i jedn¹ regu³ê kieruj¹c¹
+ komunikaty do niego w zale¿noci od poziomu. W miarê jak aplikacja ronie,
+ pojawia siê potrzeba dodawania kolejnych celów i regu³. W przypadku NLoga jest to wyj¹tkowo proste.
+ </p>
+ <h4>Informacje kontekstowe</h4>
+ <p>
+ Najwiêksz¹ si³¹ NLoga w porównaniu z innymi narzêdziami tego typu jest mechanizm formatów (ang. layouts).
+ S¹ to ma³e fragmenty tekstu otoczone par¹ nawiasów "<b>${</b>" (dolar + lewy nawias klamrowy) oraz "<b>}</b>"
+ (prawy nawias klamrowy), które potrafi¹ wstawiaæ do tekstu elementy <b>informacji kontekstowej.</b>
+ Mo¿na ich u¿ywaæ w bardzo wielu miejscach, przyk³adowo do sterowania formatem informacji wywietlanych na ekran
+ lub zapisywanych do pliku, ale tak¿e do sterowania nazwami plików!
+ </p>
+ <p>
+ Po co? Zobaczmy to na przyk³adzie. Za³ó¿my, ¿e chcemy wypisywaæ na konsolê tekstow¹ nastêpuj¹ce informacje:
+ </p>
+ <ul>
+ <li>bie¿¹ca data i godzina</li>
+ <li>nazwa klasy i metody, która spowodowa³a wypisanie komunikatu diagnostycznego</li>
+ <li>
+ poziom komunikatu diagnostycznego
+ </li>
+ <li>tekst komunikatu diagnostycznego</li>
+ </ul>
+ <p>Jak to zrobiæ? Nic prostszego:</p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="c" xsi:type="Console" layout="${longdate} ${callsite} ${level} ${message}" />
+ ]]>
+ </code>
+ <p>
+ Za³ó¿my teraz, ¿e chcemy aby komunikaty z ka¿dego ród³a trafia³y do osobnego pliku. To jest równie ³atwe:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="f" xsi:type="File" fileName="${logger}.txt" />
+ ]]>
+ </code>
+
+ <p>
+ Jak widzimy, format <font face="Courier New">${logger}</font> zosta³ tutaj u¿yty w atrybucie
+ <font face="Courier New">fileName</font>, co sprawia, ¿e ka¿dy komunikat diagnostyczny trafia do pliku o
+ nazwie takiej jak nazwa ród³a. Powy¿szy przyk³ad utworzy nam pliki:
+ </p>
+ <ul>
+ <li>Name.Space.Klasa1.txt</li>
+ <li>Name.Space.Klasa2.txt</li>
+ <li>Name.Space.Klasa3.txt</li>
+ <li>Inny.Name.Space.Klasa1.txt</li>
+ <li>Inny.Name.Space.Klasa2.txt</li>
+ <li>Inny.Name.Space.Klasa3.txt</li>
+ <li>...</li>
+ </ul>>
+ <p>Czêstym wymaganiem jest przechowywanie logów z ka¿dego dnia w osobnym pliku. To równie¿ jest trywialne:</p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="f" xsi:type="File" filename="${shortdate}.txt" />
+ ]]>
+ </code>
+ <p>
+ Gdybymy chcieli dla ka¿dego u¿ytkownika naszej aplikacji zrobiæ osobny plik, wystarczy poni¿szy fragment kodu:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="f" xsi:type="File" filename="${windows-identity:domain=false}.txt" />
+ ]]>
+ </code>
+ <p>
+ Dziêki tej prostej operacji NLog utworzy nam pliki o nazwach takich jak loginy naszych u¿ytkowników:
+ </p>
+ <ol>
+ <li>Administrator.txt</li>
+ <li>MaryManager.txt</li>
+ <li>EdwardEmployee.txt</li>
+ <li>...</li>
+ </ol>
+ <p>
+ Oczywicie mo¿liwe s¹ te¿ bardziej z³o¿one przypadki. Np. dla ka¿dego u¿ytkownika i daty tworzymy osobny
+ plik w katalogu takim jak data:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <target name="f" xsi:type="File" filename="${shortdate}/${windows-identity:domain=false}.txt" />
+ ]]>
+ </code>
+ <p>Powsta³e pliki to:</p>
+ <ol>
+ <li>2006-01-01/Administrator.txt</li>
+ <li>2006-01-01/MaryManager.txt</li>
+ <li>2006-01-01/EdwardEmployee.txt</li>
+ <li>2006-01-02/Administrator.txt</li>
+ <li>2006-01-02/MaryManager.txt</li>
+ <li>2006-01-02/EdwardEmployee.txt</li>
+ <li>...</li>
+ </ol>
+
+ <p>
+ NLog udostêpnia bardzo wiele predefiniowanych formatów. S¹ one opisane pod adresem <a href="http://www.nlog-project.org/layoutrenderers.html">http://www.nlog-project.org/layoutrenderers.html</a>.
+ Bardzo ³atwo jest tak¿e utworzyæ swój w³asny format - wymaga to zaledwie kilkunastu wierszy kodu i jest opisane w <a href="http://www.nlog-project.org/documentation.html">dokumentacji projektu</a>.
+ </p>
+
+ <h4>Pliki do³¹czane i zmienne</h4>
+ <p>
+ Czasami celowe mo¿e byæ rozbicie pliku konfiguracyjnego na kilka mniejszcych.
+ NLog udostêpnia w tym celu mechanizm plików do³¹czanych. Aby w³¹czyæ je do konfiguracji wystarczy u¿yæ
+ <x><include file="nazwapliku" /></x>. Warto wspomnieæ ¿e nazwapliku mo¿e zawieraæ elementy
+ informacji kontekstowej, wiêc mo¿liwe s¹ zaawansowane scenariusze takie jak do³¹czanie ró¿nych
+ plików na ró¿nych maszynach, jak w poni¿szym przyk³adzie, gdzie wczytujemy plik o takiej nazwie
+ jak nazwa bie¿¹cej maszyny:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <nlog>
+ ...
+ <include file="${basedir}/${machinename}.config" />
+ ...
+ </nlog>
+ ]]>
+ </code>
+ <p>
+ Zmienne pozwalaj¹ nam w skrócony sposób zapisywaæ z³o¿one lub powtarzalne wyra¿enia, takie jak nazwy plików.
+ Aby zdefiniowaæ zmienn¹ pos³ugujemy siê sk³adni¹ <x><variable name="var" value="xxx" /></x>. Aby u¿yæ jej wartoæ pos³ugujemy siê sk³adni¹
+ identyczn¹ jak przy informacjach kontekstowych, to znaczy: "${var}".
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <nlog>
+ <variable name="logDirectory" value="${basedir}/logs/${shortdate}" />
+
+ <targets>
+ <target name="file1" xsi:type="File" filename="${logDirectory}/file1.txt" />
+ <target name="file2" xsi:type="File" filename="${logDirectory}/file2.txt" />
+ </targets>
+ </nlog>
+ ]]>
+ </code>
+
+ <h4>Rekonfiguracja</h4>
+ <p>
+ Pliki konfiguracyjne s¹ standardowo wczytywane na pocz¹tku pracy programu. W przypadku d³ugo dzia³aj¹cych
+ procesów (np. us³ug systemowych) czêsto zachodzi potrzeba zwiêkszenia poziomu logowania w trakcie dzia³ania.
+ Aby umo¿liwiæ tak¹ rekonfiguracjê, NLog potrafi monitorowaæ plik konfiguracyjny aplikacji
+ i wczytywaæ go ponownie po wykryciu jakiejkolwiej zmiany. Aby w³¹czyæ ten mechanizm, wystarczy dodaæ w
+ pliku konfiguracyjnym atrybut <x><nlog autoReload="true" /></x>.
+ </p>
+
+ <h4>Rozwi¹zywanie problemów z logowaniem</h4>
+ <p>
+ Czasami zdarza siê tak, ¿e pomimo skonfigurowania, aplikacja nie zapisuje logów. Przyczyn mo¿e byæ wiele,
+ najczêstszym problemem s¹ uprawnienia, szczególnie w aplikacji webowej. Zwykle okazuje siê, ¿e serwer aplikacji
+ WWW nie ma prawa zapisu do katalogu, gdzie chcielibymy gromadziæ logi. Poniewa¿ NLog "zjada" wyj¹tki wystêpuj¹ce
+ podczas logowania, aplikacja mo¿e siê o tym nie dowiedzieæ. Jest kilka sposobów, aby stwierdziæ wystêpowanie
+ tego typu problemów.
+ </p>
+ <ul>
+ <li>
+ <x>
+ <nlog throwExceptions="true" />
+ </x>- dodanie atrybutu throwExceptions w pliku konfiguracyjnym powoduje,
+ ¿e NLog nie maskuje wyj¹tków i s¹ one przekazywane do aplikacji. Ten atrybut jest przydatny w
+ fazie uruchamiania. Po zakoñczeniu konfiguracji dobrze jest w³¹czyæ maskowanie wyj¹tków, tak aby przypadkowe
+ problemy z logowaniem nie spowodowa³y awarii naszej aplikacji.
+ </li>
+ <li>
+ <x>
+ <nlog internalLogFile="file.txt" />
+ </x>- dodanie atrybutu internalLogFilew pliku konfiguracyjnym powoduje,
+ ¿e NLog zapisze do wskazanego pliku wewnêtrzne informacje u³atwiaj¹ce debugowanie, w
+ tym wszystkie wyj¹tki jakie zostan¹ zg³oszone podczas logowania.
+ </li>
+ <li>
+ <x>
+ <nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" />
+ </x> - steruj¹cy poziomem wewnêtrznego logowania
+ </li>
+ <li>
+ <x>
+ <nlog internalLogToConsole="false|true" />
+ </x> - wysy³a zawartoæ wewnêtrznego logu na konsolê.
+ </li>
+ <li>
+ <x>
+ <nlog internalLogToConsoleError="false|true" />
+ </x> - wysy³a zawartoæ wewnêtrznego logu na wyjcie b³êdów konsoli.
+ </li>
+ </ul>
+
+ <h4>Przetwarzanie asynchroniczne, cele opakowuj¹ce i z³o¿one</h4>
+ <p>
+ Oprócz standardowych, NLog udostêpnia tak¿e tzw. wrapper targets i compound targets, czyli cele opakowuj¹ce i z³o¿one,
+ które modyfikuj¹ dzia³anie innych celów. Mog¹ dodawaæ tym samym takie funkcje jak:
+ </p>
+ <ul>
+ <li>przetwarzanie asynchroniczne (logowanie odbywa siê w osobnym w¹tku)</li>
+ <li>ponawianie próby w przypadku b³êdu</li>
+ <li>równowa¿enie obci¹¿enia (load balancing)</li>
+ <li>buforowanie</li>
+ <li>filtrowanie</li>
+ <li>cele zapasowe (w przypadku awarii jedego celu prze³¹czamy siê na kolejny)</li>
+ <li>i inne opisane na stronie <a href="http://www.nlog-project.org/targets.html">http://www.nlog-project.org/targets.html</a></li>
+ </ul>
+ <p>
+ Aby zdefiniowaæ cel z³o¿ony b¹d opakowuj¹cy w pliku konfiguracjnym, zagnie¿d¿amy
+ cel opakowany wewn¹trz odpowiedniego celu opakowuj¹cego. Zagnie¿d¿anie mo¿e byæ wielopoziomowe,
+ wiêc mo¿emy modyfikowaæ dzia³anie celu na wiêcej ni¿ jeden sposób.
+ Przyk³adowo, asynchroniczne logowanie do pliku z ponawianiem próby zapisu w przypadku b³êdu
+ definiujemy w nastêpuj¹cy sposób.:
+ </p>
+ <code lang="XML">
+ <![CDATA[
+ <targets>
+ <target name="n" xsi:type="AsyncWrapper">
+ <target xsi:type="RetryingWrapper">
+ <target xsi:type="File" fileName="${file}.txt" />
+ </target>
+ </target>
+ </targets>
+ ]]>
+ </code>
+ <p>
+ Ze wzglêdu na to, ¿e przetwarzanie asynchroniczne jest doæ czêsto stosowane,
+ NLog udostêpnia skrócon¹ sk³adniê pozwalaj¹c¹ w³¹czyæ to zachowanie dla wszystkich celów. Wystarczy w elemencie
+ <x><targets /></x> dodaæ atrybut async="true".
+ </p>
+
+ <h2>Konfiguracja programowa</h2>
+ <p>
+ Zamiast pliku konfiguracyjnego NLog mo¿e byæ konfigurowany przy pomocy API.
+ Pe³ny opis tej funkcji wykracza poza zakres artyku³u. W skrócie mo¿na powiedzieæ, ¿e polega
+ to na:
+ </p>
+ <ol>
+ <li>utworzeniu obiektu klasy LoggingConfiguration</li>
+ <li>utworzeniu jednego lub wiêcej celów (obiektów dziedzicz¹cych z klasy Target)</li>
+ <li>ustawienie w³aciwoci celów</li>
+ <li>zdefiniowanie regu³</li>
+ <li>aktywowanie konfiguracji</li>
+ </ol>
+ <p>Poni¿ej krótki przyk³ad definiuj¹cy jeden cel typu "konsola tekstowa z kolorowaniem" i drugi plikowy oraz
+ regu³ê kieruj¹c¹ do niego komunikaty na poziomie Debug lub wy¿szym:</p>
+ <code lang="C#">
+ <![CDATA[using NLog;
+using NLog.Targets;
+using NLog.Config;
+using NLog.Win32.Targets;
+
+class Example
+{
+ static void Main(string[] args)
+ {
+ // krok 1. tworzymy obiekt konfiguracji
+
+ LoggingConfiguration config = new LoggingConfiguration();
+
+ // krok 2. tworzymy cel(e) i dodajemy je do konfiguracji
+
+ ColoredConsoleTarget consoleTarget = new ColoredConsoleTarget();
+ config.AddTarget("console", consoleTarget);
+
+ FileTarget fileTarget = new FileTarget();
+ config.AddTarget("file", fileTarget);
+
+ // krok 3 - ustawiamy w³aciwoci celów
+
+ consoleTarget.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
+ fileTarget.FileName = "${basedir}/file.txt";
+ fileTarget.Layout = "${message}";
+
+ // krok 4 - definiujemy regu³y
+
+ LoggingRule rule1 = new LoggingRule("*", LogLevel.Debug, consoleTarget);
+ config.LoggingRules.Add(rule1);
+
+ LoggingRule rule2 = new LoggingRule("*", LogLevel.Debug, fileTarget);
+ config.LoggingRules.Add(rule2);
+
+ // krok 5. aktywowanie konfiguracji
+ LogManager.Configuration = config;
+
+ // przyk³ady u¿ycia
+
+ Logger logger = LogManager.GetLogger("Example");
+ logger.Trace("trace log message");
+ logger.Debug("debug log message");
+ logger.Info("info log message");
+ logger.Warn("warn log message");
+ logger.Error("error log message");
+ logger.Fatal("fatal log message");
+ }
+}]]>
+ </code>
+ <p>
+ Wynikiem dzia³ania powy¿szej aplikacji jest wypisany tekst na konsoli,
+ gdzie ka¿dy wiersz jest oznaczony kolorem wynikaj¹cym z poziomu logowania
+ i dodatkowo plik zawieraj¹cy te same informacje w nieco innym formacie.
+ </p>
+ <h2>Co jeszcze mo¿na zrobiæ w NLogu?</h2>
+ <p>
+ NLog udostêpnia jeszcze wiele funkcji, które ze wzglêdu na objêtoæ nie mog³y
+ zostaæ omówione w niniejszym artykule. Ka¿da z tych funkcji mog³aby byæ tematem na osobny artyku³.
+ </p>
+ <ul>
+ <li>
+ logowanie wyj¹tków - <a href="http://sourceforge.net/mailarchive/forum.php?thread_id=6766833&forum_id=41984">http://sourceforge.net/mailarchive/forum.php?thread_id=6766833&forum_id=41984</a>
+ </li>
+ <li>
+ jêzyk warunków logicznych u¿ywanych przy filtrowaniu - <a href="http://www.nlog-project.org/filters.html">http://www.nlog-project.org/conditions.html</a>
+ </li>
+ <li>
+ NLogViewer - aplikacja do podgl¹du logów w czasie rzeczywistym (wersja pre-alpha) - <a href="http://viewer.nlog-project.org/">http://viewer.nlog-project.org/</a>
+ </li>
+ </ul>
+ <last-changed-date>$LastChangedDate: 2006-07-10 11:32:55 +0200 (Pn, 10 lip 2006) $</last-changed-date>
+</content>
diff --git a/web/yes.gif b/web/yes.gif
new file mode 100644
index 0000000..0471844
Binary files /dev/null and b/web/yes.gif differ
diff --git a/webtest/bin/NLog.dll.nlog b/webtest/bin/NLog.dll.nlog
new file mode 100644
index 0000000..0e5f440
--- /dev/null
+++ b/webtest/bin/NLog.dll.nlog
@@ -0,0 +1,13 @@
+<nlog autoReload="true">
+ <!-- this configuration applies to NLog COM Interop, because it's located in a directory
+ where NLog.ComInterop.dll is registered. -->
+
+ <targets>
+ <appender name="aspresponse" type="ASPResponse" layout="id='${asp-request:querystring=queryparam}', form='${asp-request:form=formvariable}', cookie='${asp-request:cookie=cookie1}', servervariable='${asp-request:servervariable=URL}' item='${asp-request:item=queryparam}' session='${asp-session:variable=sv}' app='${asp-application:variable=av}' ${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="aspresponse" />
+ </rules>
+</nlog>
+
diff --git a/webtest/context.asp b/webtest/context.asp
new file mode 100644
index 0000000..33ed06d
--- /dev/null
+++ b/webtest/context.asp
@@ -0,0 +1,9 @@
+<%@ language="JScript" %>
+<%
+Response.Expires = -1;
+
+<!-- this uses a ASP response target -->
+var logger = new ActiveXObject("NLog.Logger");
+logger.LoggerName = "logger";
+logger.Debug("message");
+%>
diff --git a/webtest/context.aspx b/webtest/context.aspx
new file mode 100644
index 0000000..9d8949e
--- /dev/null
+++ b/webtest/context.aspx
@@ -0,0 +1,19 @@
+<%@ Page language="c#" AutoEventWireup="true" %>
+<script language="C#" runat="server">
+NLog.Logger logger = NLog.LogManager.GetLogger("Memory");
+
+void Page_Load(Object sender, EventArgs e)
+{
+ Response.Expires = -1;
+ NLog.Targets.MemoryTarget memoryTarget = NLog.LogManager.Configuration.FindTargetByName("memory") as NLog.Targets.MemoryTarget;
+
+ memoryTarget.Logs.Clear();
+
+ logger.Debug("message");
+
+ foreach (string s in memoryTarget.Logs)
+ {
+ Response.Write(s);
+ }
+}
+</script>
diff --git a/webtest/global.asa b/webtest/global.asa
new file mode 100644
index 0000000..b218c6c
--- /dev/null
+++ b/webtest/global.asa
@@ -0,0 +1,11 @@
+<script language="JScript" runat="Server">
+function Application_OnStart()
+{
+ Application("av") = "appvalue2";
+}
+
+function Session_OnStart()
+{
+ Session("sv") = "sessionvalue2";
+}
+</script>
diff --git a/webtest/global.asax b/webtest/global.asax
new file mode 100644
index 0000000..c2fe70b
--- /dev/null
+++ b/webtest/global.asax
@@ -0,0 +1,63 @@
+<%@ Application %>
+<script language="C#" runat="server">
+NLog.Logger logger = NLog.LogManager.GetLogger("Global.Logger");
+
+protected void Application_Start(Object sender, EventArgs e)
+{
+ logger.Info("Application_Start");
+ Application["av"] = "appvalue1";
+}
+
+protected void Session_Start(Object sender, EventArgs e)
+{
+ logger.Info("Session_Start");
+ Session["sv"] = "sessionvalue1";
+}
+
+protected void Application_BeginRequest(Object sender, EventArgs e)
+{
+ logger.Info("Application_BeginRequest");
+}
+
+protected void Application_EndRequest(Object sender, EventArgs e)
+{
+ logger.Info("Application_EndRequest");
+}
+
+protected void Application_AuthenticateRequest(Object sender, EventArgs e)
+{
+ logger.Info("Application_AuthenticateRequest");
+}
+
+protected void Application_Error(Object sender, EventArgs e)
+{
+ logger.Info("Application_Error");
+}
+
+protected void Session_End(Object sender, EventArgs e)
+{
+ logger.Info("Session_End");
+}
+
+protected void Application_End(Object sender, EventArgs e)
+{
+ logger.Info("Application_End");
+}
+
+protected void Application_AuthorizeRequest(object sender, EventArgs e)
+{
+ logger.Info("Application_AuthorizeRequest");
+}
+
+protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
+{
+ logger.Info("Application_PreRequestHandlerExecute");
+}
+
+protected void Application_PostRequestHandlerExecute(object sender, EventArgs e)
+{
+ HttpContext.Current.Trace.Write("aaa");
+//throw new Exception("ex");
+ logger.Info("Application_PostRequestHandlerExecute");
+}
+</script>
diff --git a/webtest/test.aspx b/webtest/test.aspx
new file mode 100644
index 0000000..e899ff0
--- /dev/null
+++ b/webtest/test.aspx
@@ -0,0 +1,13 @@
+<%@ Page language="c#" AutoEventWireup="true" %>
+<script language="C#" runat="server">
+NLog.Logger logger = NLog.LogManager.GetLogger("default.aspx");
+
+void Page_Load(Object sender, EventArgs e)
+{
+ logger.Info("got Page_Load() event");
+ logger.Warn("Some warning...");
+ logger.Error("Some error...");
+
+ Response.Write("loaded!");
+}
+</script>
diff --git a/webtest/web.config b/webtest/web.config
new file mode 100644
index 0000000..4cee9c6
--- /dev/null
+++ b/webtest/web.config
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <configSections>
+ <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
+ </configSections>
+ <system.web>
+ <compilation defaultLanguage="c#" debug="true" />
+ <customErrors mode="Off" />
+ <trace enabled="true" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="false" />
+ <sessionState mode="InProc" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" cookieless="false" timeout="20" />
+ <globalization requestEncoding="utf-8" responseEncoding="utf-8" />
+ </system.web>
+ <nlog>
+
+ <!-- this configuration applies to ASP.NET only, classic ASP configuration can be found in "bin/NLog.dll.nlog" -->
+
+ <targets>
+ <appender name="aspnet" type="ASPNetTrace" layout="${level} ${message}" />
+ <appender name="memory" type="Memory" layout="id='${aspnet-request:querystring=queryparam}', form='${aspnet-request:form=formvariable}', cookie='${aspnet-request:cookie=cookie1}', servervariable='${aspnet-request:servervariable=URL}' item='${aspnet-request:item=queryparam}' session='${aspnet-session:variable=sv}' app='${aspnet-application:variable=av}' ${message}" />
+ </targets>
+
+ <rules>
+ <logger name="*" minlevel="Debug" writeTo="aspnet" />
+ <logger name="Memory" minlevel="Debug" writeTo="memory" />
+ </rules>
+ </nlog>
+</configuration>
--
nlog
More information about the Pkg-cli-libs-commits
mailing list