如何使用NLog序列化对象字段? [英] How to serialize object fields with NLog?

查看:83
本文介绍了如何使用NLog序列化对象字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在测试新的结构化日志但是并不能真正做到这一点.

Im testing out the new structured logging but do not really get it right.

我的nlog.config中有这个文件:

I have this in my nlog.config :

<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log">
  <layout xsi:type="JsonLayout" includeAllProperties="true">${longdate}|${level}|${logger}|${message}</layout>
</target>

<logger name="CommunicationLogger" minlevel="Info" writeto="f"></logger>

我的日志代码如下:

public void LogCommunication(string operation, List<object> args)
    {
        var parameters = new List<object>();

        var text = "Operation:{Operation} ";
        parameters.Add(operation);

        text += "PersonId:{PersonId} ";
        parameters.Add(SharedContext.GetMyUserContext().CurrentPersonId);

        text += "ClientMachineName:{ComputerName} ";
        parameters.Add(SharedContext.GetMyUserContext().ClientMachineName);

        text += "Servername:{MachineName} ";
        parameters.Add(Environment.MachineName);

        if (args != null)
        {
            foreach(var param in args)
            {
                text += "Param:{@Parameters} ";
                parameters.Add(param);
            }

        }

        _log.LogCommunication(text, parameters.ToArray());
    }

public void LogCommunication(string message, params object[] args)
        {
            _comLogger.Log(LogLevel.Info, message, args);
        }

输出看起来像这样:

{"Operation":"OperationName","PersonId":1,"ComputerName": "MyComputername","MachineName":"MyMachinename","Parameters": {"LocationKeyList":[],"MyObjectIdList":[],"RolList":[]}}

{ "Operation": "OperationName", "PersonId": 1, "ComputerName": "MyComputername", "MachineName": "MyMachinename", "Parameters": {"LocationKeyList":[], "MyObjectIdList":[], "RolList":[]} }

我希望参数也可以序列化,而不只是showint [],这样我就可以看到服务操作的所有参数.该参数是带有dataContract(WCF)的复杂类型.

I would like the Parameters to also get serialize instead of just showint [] so I can see all the parameters of the service operation. The parameter is a complex type with dataContract(WCF).

是否有一种简单的方法来获取用于结构数据的参数.

Is there a simple way to get the parameters to work with structural data.

Retagards

Retagards

Update1

nlog.config

nlog.config

<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log">
  <layout xsi:type="JsonLayout" includeAllProperties="true" maxRecursionLimit="10">
    <attribute name="time" layout="${longdate}" />
    <attribute name="level" layout="${level}"/>
    <attribute name="message" layout="${message}" />
  </layout>
</target>

设置数据的代码

var parameters = new List<object>();

            var text = "{TimeStamp} - ";
            parameters.Add(DateTime.Now);

            text += "Duration:{Duration} ";
            parameters.Add(Timestamp);

            text += "Operation:{Operation} ";
            parameters.Add(operation);

            text += "PersonId:{PersonId} ";
            parameters.Add(SharedContext.GetMyUserContext().CurrentPersonId);

            text += "ClientMachineName:{ComputerName} ";
            parameters.Add(SharedContext.GetMyUserContext().ClientMachineName);

            text += "Servername:{MachineName} ";
            parameters.Add(Environment.MachineName);

            if (args != null && args.Count() > 0)
            {
                text += "Param:{@Parameters} ";
                parameters.Add(args);
            }

            _log.LogCommunication(text, parameters.ToArray());

结果:

ientMachineName:\"MyComputer \"服务器名称:\"MyComputer \" 参数:[\"MyApp.ServiceContracts.GetEntityViewRequest \"], 时间戳记":"2020-04-08T23:30:59.7725147Z",持续时间": "00:00:00.0009930",操作":"GetReferenceData","PersonId":1, 计算机名称":"SE-MyCom",计算机名称":"SE-MyCom", 参数":["MyApp.ServiceContracts.GetEntityViewRequest"]}

ientMachineName:\"MyComputer\" Servername:\"MyComputer\" Param:[\"MyApp.ServiceContracts.GetEntityViewRequest\"] ", "TimeStamp": "2020-04-08T23:30:59.7725147Z", "Duration": "00:00:00.0009930", "Operation": "GetReferenceData", "PersonId": 1, "ComputerName": "SE-MyCom", "MachineName": "SE-MyCom", "Parameters": ["MyApp.ServiceContracts.GetEntityViewRequest"] }

{时间":"2020-04-09 01:31:00.3637",级别":信息",消息": "2020-04-09 01:31:00-持续时间:00:00:00.5594936 操作:\"GetExternaAnrop \" PersonId:1 ClientMachineName:\"MyComputer \"服务器名称:\"MyComputer \" 参数:[{\"PlaceringKeyList \":[],\"ArbetsstalleIdList \":[], \"RollList \":[]}]," TimeStamp:" 2020-04-08T23:31:00.363752Z, "Duration":"00:00:00.5594936","Operation":"GetExternaAnrop", "PersonId":1,"ComputerName":"SE-MyCom","MachineName": "SE-MyCom",参数":[{"PlaceringKeyList":[], "ArbetsstalleIdList":[],"RollList":[]}]}

{ "time": "2020-04-09 01:31:00.3637", "level": "Info", "message": "2020-04-09 01:31:00 - Duration:00:00:00.5594936 Operation:\"GetExternaAnrop\" PersonId:1 ClientMachineName:\"MyComputer\" Servername:\"MyComputer\" Param:[{\"PlaceringKeyList\":[], \"ArbetsstalleIdList\":[], \"RollList\":[]}] ", "TimeStamp": "2020-04-08T23:31:00.363752Z", "Duration": "00:00:00.5594936", "Operation": "GetExternaAnrop", "PersonId": 1, "ComputerName": "SE-MyCom", "MachineName": "SE-MyCom", "Parameters": [{"PlaceringKeyList":[], "ArbetsstalleIdList":[], "RollList":[]}] }

Update2

我有一个如下所示的服务方法:

I have a service method that looks like this :

GetEntityViewResponse GetReferenceData(GetEntityViewRequest request);

请求类如下:

[DataContract]
    public class GetEntityViewRequest
    {
        public GetEntityViewRequest(params EntityViewKey[] Keys)
        {
            EntityViewKeys.AddRange(Keys);
        }
        public GetEntityViewRequest(params int[] EgnaKodtyper)
        {
            MyList.AddRange(EgnaKodtyper);
        }
        public GetEntityViewRequest()
        {

        }
        [DataMember]
        public List<EntityViewKey> EntityViewKeys = new List<EntityViewKey>();
        [DataMember]
        public List<int> MyList= new List<int>();
    }

运行代码(发送请求)时,我可以在服务端的messageInspector中看到我已获取数据. EntityViewKeys有一个枚举集.

When running the code(sending the request) I can see in my messageInspector on the serviceside that I got data. The EntityViewKeys have a enum set.

NLog输出看起来像这样:

The NLog output looks like this :

{时间":"2020-04-12 19:27:55.6690",级别":信息",消息": "2020-04-12 19:27:55-持续时间:00:00:00.0034730 操作:\"GetReferenceData \" PersonId:1 ClientMachineName:\"MyComputer \"服务器名称:\"MyComputer \" 参数:[\"Orbit.ServiceContracts.GetEntityViewRequest \"], 时间戳记":"2020-04-12T17:27:55.6690745Z",持续时间": "00:00:00.0034730",操作":"GetReferenceData","PersonId":1, 计算机名称":"SE-MyCom",计算机名称":"SE-MyCom", 参数":["Orbit.ServiceContracts.GetEntityViewRequest"]}

{ "time": "2020-04-12 19:27:55.6690", "level": "Info", "message": "2020-04-12 19:27:55 - Duration:00:00:00.0034730 Operation:\"GetReferenceData\" PersonId:1 ClientMachineName:\"MyComputer\" Servername:\"MyComputer\" Param:[\"Orbit.ServiceContracts.GetEntityViewRequest\"] ", "TimeStamp": "2020-04-12T17:27:55.6690745Z", "Duration": "00:00:00.0034730", "Operation": "GetReferenceData", "PersonId": 1, "ComputerName": "SE-MyCom", "MachineName": "SE-MyCom", "Parameters": ["Orbit.ServiceContracts.GetEntityViewRequest"] }

因此,即使该类并不复杂,它仍不会在NLog中打印内容?

So even if the class is not complex it is still not printing the content in NLog?

推荐答案

JsonLayout有一个重要参数称为MaxRecursionLimit(默认值= 0,直到NLog v5到达):

There is an important parameter for JsonLayout called MaxRecursionLimit (Default = 0 until NLog v5 arrives):

https://github.com/nlog/nlog/wiki/JsonLayout

因此您可以执行以下操作:

So you can do this:

<layout xsi:type="JsonLayout" includeAllProperties="true" maxRecursionLimit="10">
              <attribute name="time" layout="${longdate}" />
              <attribute name="level" layout="${level}"/>
              <attribute name="message" layout="${message}" />
</layout>

也许您想将参数更改为此:

Maybe you want to change your parameters into this:

if (args != null)
{
    text += "Params:{@Parameters} ";
    parameters.Add(args);
}

默认情况下,NLog不会序列化对象字段,而只会序列化对象属性.如果必须填写字段,则可以使用NLog 4.7设置安装程序自定义反射:

NLog will by default not serialize object-fields, but only object-properties. If fields are a must, then you can setup setup custom reflection with NLog 4.7:

LogManager.Setup().SetupSerialization(s =>
   s.RegisterObjectTransformation<GetEntityViewResponse>(obj => new {
      EntityViewKeys = obj.EntityViewKeys,
      MyList = obj.MyList,
   })
);

或者,如果您是一个懒惰的人:

Or if you are a lazy person:

LogManager.Setup().SetupSerialization(s =>
   s.RegisterObjectTransformation<GetEntityViewRequest>(obj => 
       return Newtonsoft.Json.Linq.JToken.FromObject(obj) // Lazy and slow
   )
);

这篇关于如何使用NLog序列化对象字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆