[Target("MyFirst")]
public sealed class MyFirstTarget : AsyncTaskTarget
{
public MyFirstTarget()
{
this.Host = "localhost";
}
[RequiredParameter]
public Layout Host { get; set; }
protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
{
string logMessage = this.RenderLogEvent(this.Layout, logEvent);
string hostName = this.RenderLogEvent(this.Host, logEvent);
return SendTheMessageToRemoteHost(hostName, logMessage);
}
private async Task SendTheMessageToRemoteHost(string hostName, string message)
{
// To be implemented
}
}
protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
{
return CustomWriteAsync(logEvent, token);
}
private async Task CustomWriteAsync(LogEventInfo logEvent, CancellationToken token)
{
await MyLogMethodAsync(logEvent, token).ConfigureAwait(false);
}
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
${basedir}/${level}.log
All To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
To print the results, use any application that's able to receive messages over TCP or UDP. NetCat 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.
There are two specialized versions of the Network target: Chainsaw and NLogViewer which write to instances of Chainsaw log4j viewer or NLogViewer application respectively.
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
[Target("MyFirst")]
public sealed class MyFirstTarget : TargetWithContext
{
public MyFirstTarget()
{
this.Host = "localhost";
}
[RequiredParameter]
public Layout Host { get; set; }
protected override void Write(LogEventInfo logEvent)
{
string logMessage = this.RenderLogEvent(this.Layout, logEvent);
string hostName = this.RenderLogEvent(this.Host, logEvent);
return SendTheMessageToRemoteHost(hostName, logMessage);
}
private void SendTheMessageToRemoteHost(string hostName, string message)
{
// To be implemented
}
}
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
<system.net>
<defaultProxy enabled = "true" useDefaultCredentials = "true" >
<proxy usesystemdefault = "True" />
</defaultProxy>
</system.net>
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
The example web service that works with this example is shown below
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.
Because asynchronous logging is quite a common scenario, NLog supports a shorthand notation for wrapping all targets with AsyncWrapper. Just add async="true" to the <targets/> element in the configuration file.
... your targets go here ...
]]>
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
This example causes the messages to be written to server1, and if it fails, messages go to server2.
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
This example causes the messages not contains the string '1' to be ignored.
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
This example works like this. If there are no Warn,Error or Fatal messages in the buffer only Info messages are written to the file, but if there are any warnings or errors, the output includes detailed trace (levels >= Debug). You can plug in a different type of buffering wrapper (such as ASPNetBufferingWrapper) to achieve different functionality.
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
This example causes the messages to be written to either file1.txt or file2.txt chosen randomly on a per-message basis.
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
This example causes each log message to be repeated 3 times.
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
This example causes each write attempt to be repeated 3 times, sleeping 1 second between attempts if first one fails.
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
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.
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
This example causes the messages to be written to both file1.txt or file2.txt
To set up the target in the configuration file, use the following syntax:
To set up the log target programmatically use code like this:
[CanBeNull] object Test() => null;
void UseTest() {
var p = Test();
var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
}
[NotNull] object Foo() {
return null; // Warning: Possible 'null' assignment
}
public void Foo([ItemNotNull]List<string> books)
{
foreach (var book in books) {
if (book != null) // Warning: Expression is always true
Console.WriteLine(book.ToUpper());
}
}
public void Foo([ItemCanBeNull]List<string> books)
{
foreach (var book in books)
{
// Warning: Possible 'System.NullReferenceException'
Console.WriteLine(book.ToUpper());
}
}
[StringFormatMethod("message")]
void ShowError(string message, params object[] args) { /* do something */ }
void Foo() {
ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
}
void LogInfo([StructuredMessageTemplate]string message, params object[] args) { /* do something */ }
void Foo() {
LogInfo("User created: {username}"); // Warning: Non-existing argument in format string
}
namespace TestNamespace
{
public class Constants
{
public static int INT_CONST = 1;
public const string STRING_CONST = "1";
}
public class Class1
{
[ValueProvider("TestNamespace.Constants")] public int myField;
public void Foo([ValueProvider("TestNamespace.Constants")] string str) { }
public void Test()
{
Foo(/*try completion here*/);//
myField = /*try completion here*/
}
}
}
void Foo([ValueRange(0, 100)] int value) {
if (value == -1) { // Warning: Expression is always 'false'
...
}
}
void Foo([NonNegativeValue] int value) {
if (value == -1) { // Warning: Expression is always 'false'
...
}
}
void Foo(string param) {
if (param == null)
throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
}
public class Foo : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void NotifyChanged(string propertyName) { ... }
string _name;
public string Name {
get { return _name; }
set { _name = value; NotifyChanged("LastName"); /* Warning */ }
}
}
Examples of generated notifications:
Function Definition Table syntax:
[ContractAnnotation("=> halt")]
public void TerminationMethod()
[ContractAnnotation("null <= param:null")] // reverse condition syntax
public string GetName(string surname)
[ContractAnnotation("s:null => true")]
public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
// A method that returns null if the parameter is null,
// and not null if the parameter is not null
[ContractAnnotation("null => null; notnull => notnull")]
public object Transform(object data)
[ContractAnnotation("=> true, result: notnull; => false, result: null")]
public bool TryParse(string s, out Person result)
[LocalizationRequiredAttribute(true)]
class Foo {
string str = "my string"; // Warning: Localizable string
}
[CannotApplyEqualityOperator]
class NoEquality { }
class UsesNoEquality {
void Test() {
var ca1 = new NoEquality();
var ca2 = new NoEquality();
if (ca1 != null) { // OK
bool condition = ca1 == ca2; // Warning
}
}
}
[BaseTypeRequired(typeof(IComponent)] // Specify requirement
class ComponentAttribute : Attribute { }
[Component] // ComponentAttribute requires implementing IComponent interface
class MyComponent : IComponent { }
[UsedImplicitly]
public class TypeConverter {}
public class SummaryData
{
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedWithFixedConstructorSignature)]
public SummaryData() {}
}
[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors | ImplicitUseTargetFlags.Default)]
public interface IService {}
[Pure] int Multiply(int x, int y) => x * y;
void M() {
Multiply(123, 42); // Warning: Return value of pure method is not used
}
[MustUseReturnValue("Use the return value to...")]
.
class Foo {
[ProvidesContext] IBarService _barService = ...;
void ProcessNode(INode node) {
DoSomething(node, node.GetGlobalServices().Bar);
// ^ Warning: use value of '_barService' field
}
}
[SourceTemplate]
public static void forEach<T>(this IEnumerable<T> xs) {
foreach (var x in xs) {
//$ $END$
}
}
[SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")]
public static void forEach<T>(this IEnumerable<T> collection) {
foreach (var item in collection) {
//$ $END$
}
}
Applying the attribute on a template method parameter:
[SourceTemplate]
public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) {
/*$ var $x$Id = "$newguid$" + x.ToString();
x.DoSomething($x$Id); */
}
public class MyStringCollection : List<string>
{
[CollectionAccess(CollectionAccessType.Read)]
public string GetFirstString()
{
return this.ElementAt(0);
}
}
class Test
{
public void Foo()
{
// Warning: Contents of the collection is never updated
var col = new MyStringCollection();
string x = col.GetFirstString();
}
}
static void ThrowIfNull<T>([NoEnumeration] T v, string n) where T : class
{
// custom check for null but no enumeration
}
void Foo(IEnumerable<string> values)
{
ThrowIfNull(values, nameof(values));
var x = values.ToList(); // No warnings about multiple enumeration
}
void Foo([LanguageInjection(InjectedLanguage.CSS, Prefix = "body{", Suffix = "}")] string cssProps)
{
// cssProps should only contains a list of CSS properties
}