Post

NLog.Targets.Syslog 사용법

C# .net core에서 NLOG를 이용한 XML 사용법

  • 우선 NuGet을 통해 NLog와 NLog.Targets.Syslog를 설치합니다.
  • syslog는 Rfc5424와 같은 규격을 사용하기 때문에 아무렇게나 log를 만들 수 없습니다. 따라서 특정 규격에 맞게 데이터를 전송해야하는데 NLog가 그것을 담당해줍니다.
  • 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:sl="http://www.nlog-project.org/schemas/NLog.Targets.Syslog.xsd">
  <targets>
    <target name="Updater" xsi:type="File" fileName="${basedir}/logs/updater${cached:cached=true:inner=${date:format=yyyy-MM-dd}}.log" archiveFileName="${basedir}/logs/Updater{#}.log" archiveAboveSize="2048000" concurrentWrites="true" keepFileOpen="true" archiveEvery="Day" archiveNumbering="Rolling" archiveDateFormat="yyyy-MM-dd" maxArchiveFiles="30" layout="${longdate} ${uppercase:${level}} ${stacktrace} ${message}" />
    <target name="SysLog" xsi:type="File" fileName="${basedir}/../Log/Sys/Sys.log" archiveFileName="${basedir}/../Log/Sys/Sys_{#}.log" archiveNumbering="Date" archiveDateFormat="yyyy-MM-dd" archiveEvery="Day" ArchiveOldFileOnStartup="true" maxArchiveFiles="90" concurrentWrites="true" keepFileOpen="true" openFileCacheTimeout="30" layout="${longdate} ${uppercase:${level}} ${stacktrace} ${message}" />
    <target name="Udp" xsi:type="Chainsaw" address="udp://127.0.0.1:7071" />

    <target name="ApiLog" xsi:type="File" fileName="${basedir}/../Log/WebApi/API/APILog.log" archiveFileName="${basedir}/../Log/WebApi/API/APILog_{#}.log" archiveNumbering="Date" archiveDateFormat="yyyy-MM-dd" archiveEvery="Day" ArchiveOldFileOnStartup="true" maxArchiveFiles="90" concurrentWrites="true" keepFileOpen="true" openFileCacheTimeout="30" layout="${longdate} ${uppercase:${level}} ${stacktrace} ${message}" />

    <target name="SyslogNG" xsi:type="Syslog">
      <sl:layout xsi:type="SimpleLayout" text="${level:uppercase=true}|${message}|${logger}|${exception}" />
      <sl:messageCreation>
        <sl:facility>Local1</sl:facility>
        <sl:rfc>Rfc5424</sl:rfc>
        <sl:rfc5424>
          <sl:hostname xsi:type="SimpleLayout" text="${machinename}" />
          <sl:appName xsi:type="SimpleLayout" text="${appdomain:format={1\}}" />
          <sl:disableBom>true</sl:disableBom>
        </sl:rfc5424>
      </sl:messageCreation>
      <sl:messageSend>
        <sl:protocol>Udp</sl:protocol>
        <sl:udp>
          <sl:server>192.168.0.92</sl:server>
          <sl:port>7071</sl:port>
        </sl:udp>
      </sl:messageSend>
    </target>
  </targets>
  <rules>
    <logger name="*" minlevel="Trace" writeTo="SysLog,Udp,SyslogNG" />
    <logger name="Something.Model.Context" level="Debug" writeTo="ApiLog" />
    <logger name="*" minlevel="Trace" writeTo="SvcLog">
      <filters>
        <when condition="equals('${logger}','Something.Model.Context')" action="Ignore" />
      </filters>
    </logger>
  </rules>
</nlog>
  • Syslog가 정상적으로 읽혀지지 않을때에는 new NLog.Targets.Syslog.SyslogTarget();를 통해 초기화를 해주면 위의 내용을 정상적으로 읽어들일 수 있습니다.
  • 다음 코드로 Logger를 작성 할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using NLog;

public class HLogger
{
    private static readonly NLog.Logger Logger = LogManager.GetCurrentClassLogger();

    static HLogger()
    {
        new NLog.Targets.Syslog.SyslogTarget();

        var path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
        if (path == null) return;

        path = path.Replace("file:\\", string.Empty);

        var targetDic = new Dictionary<string, List<string>>();
        targetDic.Add("system.exe", new List<string>() { "ApiLog", "SyslogNG", "Udp" });
        targetDic.Add("core.dll", new List<string>() { "Updater", "SysLog", "SvcLog" });
        
        var files = Directory.EnumerateFiles(path).Where(x => targetDic.ContainsKey(new FileInfo(x).Name.ToLower()))
                                                  .Select(x => new FileInfo(x).Name.ToLower());

        if (!files.Any())
        {
            foreach (var target in LogManager.Configuration.AllTargets)
            {
                LogManager.Configuration.RemoveTarget(target.Name);
            }
            return;
        }

        foreach (var file in files)
        {
            foreach (var target in targetDic[file])
            {
                LogManager.Configuration.RemoveTarget(target);
            }
        }
    }

    /// <summary>
    /// Write Debug Log : Parameter Validation
    /// </summary>
    public static void Debug(string log, [CallerFilePath] string fileName = "", [CallerMemberName] string memberName = "")
    {
        Logger.Debug($"{Path.GetFileNameWithoutExtension(fileName)}.{memberName}() - {log}");
    }

    /// <summary>
    /// Write Info Log : Start Point - End Point
    /// </summary>
    public static void Info(string log, [CallerFilePath] string fileName = "", [CallerMemberName] string memberName = "")
    {
        Logger.Info($"{Path.GetFileNameWithoutExtension(fileName)}.{memberName}() - {log}");
    }

    /// <summary>
    /// Write Error Log : Exception
    /// </summary>
    public static void Error(string log, [CallerFilePath] string fileName = "", [CallerMemberName] string memberName = "")
    {
        Logger.Error($"{Path.GetFileNameWithoutExtension(fileName)}.{memberName}() - {log}");
    }

    /// <summary>
    /// Write Warning Log : Performance Count
    /// </summary>
    public static void Warn(string log, [CallerFilePath] string fileName = "", [CallerMemberName] string memberName = "")
    {
        Logger.Warn($"{Path.GetFileNameWithoutExtension(fileName)}.{memberName}() - {log}");
    }
}
This post is licensed under CC BY 4.0 by the author.