Subversion Repositories SoapBoxCore

Compare Revisions

Ignore whitespace Rev 1 → Rev 2

/trunk/src/NLog/MDC.cs
New file
0,0 → 1,124
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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();
}
}
/trunk/src/NLog/Conditions/ConditionLevelExpression.cs
New file
0,0 → 1,70
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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";
}
}
}
/trunk/src/NLog/Conditions/ConditionParseException.cs
New file
0,0 → 1,76
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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
}
}
/trunk/src/NLog/Conditions/ConditionParser.cs
New file
0,0 → 1,243
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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;
}
}
}
/trunk/src/NLog/Conditions/ConditionLayoutExpression.cs
New file
0,0 → 1,88
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Conditions/ConditionExpression.cs
New file
0,0 → 1,61
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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)
{
}
}
}
/trunk/src/NLog/Conditions/ConditionLoggerNameExpression.cs
New file
0,0 → 1,70
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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";
}
}
}
/trunk/src/NLog/Conditions/ConditionMethodExpression.cs
New file
0,0 → 1,138
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
}
/trunk/src/NLog/Conditions/ConditionOrExpression.cs
New file
0,0 → 1,100
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Conditions/ConditionMethods.cs
New file
0,0 → 1,107
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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;
}
}
}
/trunk/src/NLog/Conditions/ConditionMessageExpression.cs
New file
0,0 → 1,70
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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";
}
}
}
/trunk/src/NLog/Conditions/ConditionRelationalOperator.cs
New file
0,0 → 1,71
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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 (&lt;)
/// </summary>
Less,
 
/// <summary>
/// Greater than (&gt;)
/// </summary>
Greater,
 
/// <summary>
/// Less than or equal (&lt;=)
/// </summary>
LessOrEqual,
 
/// <summary>
/// Greater than or equal (&gt;=)
/// </summary>
GreaterOrEqual,
}
}
/trunk/src/NLog/Conditions/ConditionRelationalExpression.cs
New file
0,0 → 1,195
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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>&lt;</b>, <b>&lt;=</b>,
/// <b>&gt;</b> or <b>&gt;=</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);
}
}
}
/trunk/src/NLog/Conditions/ConditionTokenizer.cs
New file
0,0 → 1,459
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Conditions/ConditionExpressionCollection.cs
New file
0,0 → 1,243
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Conditions/ConditionLiteralExpression.cs
New file
0,0 → 1,77
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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();
}
}
}
/trunk/src/NLog/Conditions/ConditionNotExpression.cs
New file
0,0 → 1,71
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Conditions/ConditionTokenType.cs
New file
0,0 → 1,73
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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,
};
}
/trunk/src/NLog/Conditions/ConditionAndExpression.cs
New file
0,0 → 1,107
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Targets/NLogViewer.cs
New file
0,0 → 1,195
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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; }
}
}
}
/trunk/src/NLog/Targets/DatabaseParameterInfo.cs
New file
0,0 → 1,132
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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; }
}
}
}
/trunk/src/NLog/Targets/Mail.cs
New file
0,0 → 1,463
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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@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@domain.com;jane@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@domain.com;jane@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@domain.com;jane@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
/trunk/src/NLog/Targets/Debugger.cs
New file
0,0 → 1,105
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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
/trunk/src/NLog/Targets/RichTextBoxWordColoringRule.cs
New file
0,0 → 1,195
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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
/trunk/src/NLog/Targets/Debug.cs
New file
0,0 → 1,94
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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; }
}
}
}
/trunk/src/NLog/Targets/MethodCallParameterCollection.cs
New file
0,0 → 1,248
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Targets/Network.cs
New file
0,0 → 1,338
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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;
}
}
}
}
/trunk/src/NLog/Targets/RichTextBoxRowColoringRuleCollection.cs
New file
0,0 → 1,255
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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
/trunk/src/NLog/Targets/MessageBox.cs
New file
0,0 → 1,132
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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));
}
}
}
/trunk/src/NLog/Targets/DatabaseParameterInfoCollection.cs
New file
0,0 → 1,249
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Targets/Chainsaw.cs
New file
0,0 → 1,85
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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;
}
}
}
/trunk/src/NLog/Targets/NLogViewerParameterInfo.cs
New file
0,0 → 1,89
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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; }
}
}
}
/trunk/src/NLog/Targets/Trace.cs
New file
0,0 → 1,87
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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
/trunk/src/NLog/Targets/WebService.cs
New file
0,0 → 1,266
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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();
}
}
}
/trunk/src/NLog/Targets/Wrappers/FilteringRuleCollection.cs
New file
0,0 → 1,249
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Targets/Wrappers/RepeatTargetWrapper.cs
New file
0,0 → 1,129
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Targets/Wrappers/ASPNetBufferingTargetWrapper.cs
New file
0,0 → 1,235
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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
/trunk/src/NLog/Targets/Wrappers/PostFilteringWrapper.cs
New file
0,0 → 1,196
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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 &gt;= 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);
}
}
}
/trunk/src/NLog/Targets/Wrappers/FilteringRule.cs
New file
0,0 → 1,100
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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; }
}
}
}
/trunk/src/NLog/Targets/Wrappers/RetryTargetWrapper.cs
New file
0,0 → 1,138
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
}
}
/trunk/src/NLog/Targets/Wrappers/BufferingTargetWrapper.cs
New file
0,0 → 1,206
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
}
}
/trunk/src/NLog/Targets/Wrappers/ImpersonatingWrapper.cs
New file
0,0 → 1,390
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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
/trunk/src/NLog/Targets/Wrappers/AutoFlushTargetWrapper.cs
New file
0,0 → 1,94
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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();
}
}
}
/trunk/src/NLog/Targets/Wrappers/WrapperTargetBase.cs
New file
0,0 → 1,110
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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") + ")";
}
}
}
/trunk/src/NLog/Targets/Wrappers/FilteringWrapper.cs
New file
0,0 → 1,125
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
 
}
}
/trunk/src/NLog/Targets/Wrappers/AsyncTargetWrapper.cs
New file
0,0 → 1,454
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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 &lt;targets/&gt; 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; }
}
}
 
}
}
/trunk/src/NLog/Targets/RichTextBoxWordColoringRuleCollection.cs
New file
0,0 → 1,240
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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
/trunk/src/NLog/Targets/Console.cs
New file
0,0 → 1,128
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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();
}
}
}
/trunk/src/NLog/Targets/RichTextBox.cs
New file
0,0 → 1,260
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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
/trunk/src/NLog/Targets/Database.cs
New file
0,0 → 1,439
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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 &lt;parameters />&gt; 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 &lt;parameters />&lt; 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;
}
}
}
/trunk/src/NLog/Targets/FormControl.cs
New file
0,0 → 1,147
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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
/trunk/src/NLog/Targets/Memory.cs
New file
0,0 → 1,81
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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; }
}
}
}
/trunk/src/NLog/Targets/ASPNetTrace.cs
New file
0,0 → 1,108
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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
/trunk/src/NLog/Targets/Null.cs
New file
0,0 → 1,87
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
}
/trunk/src/NLog/Targets/NLogViewerParameterInfoCollection.cs
New file
0,0 → 1,249
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Targets/MethodCall.cs
New file
0,0 → 1,127
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
}
/trunk/src/NLog/Targets/MethodCallParameter.cs
New file
0,0 → 1,137
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Targets/MethodCallTargetBase.cs
New file
0,0 → 1,94
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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; }
}
}
}
/trunk/src/NLog/Targets/File.cs
New file
0,0 → 1,1344
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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;
}
}
}
}
/trunk/src/NLog/Targets/RichTextBoxRowColoringRule.cs
New file
0,0 → 1,161
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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
/trunk/src/NLog/Targets/Compound/RoundRobinTarget.cs
New file
0,0 → 1,108
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Targets/Compound/RandomizeTarget.cs
New file
0,0 → 1,99
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
/trunk/src/NLog/Targets/Compound/SplitTarget.cs
New file
0,0 → 1,98
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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);
}
}
}
}
/trunk/src/NLog/Targets/Compound/CompoundTargetBase.cs
New file
0,0 → 1,118
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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();
}
}
}
}
/trunk/src/NLog/Targets/Compound/FallbackTarget.cs
New file
0,0 → 1,136
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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;
}
}
}
}
}
}
/trunk/src/NLog/Internal/MethodInfoDictionary.cs
New file
0,0 → 1,164
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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; }
}
}
}
/trunk/src/NLog/Internal/StringCollection.cs
New file
0,0 → 1,231
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (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
/trunk/src/NLog/Internal/PropertyHelper.cs
New file
0,0 → 1,392
//
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the a