首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Log4Net PatternString中添加自定义字段

在Log4Net PatternString中添加自定义字段
EN

Stack Overflow用户
提问于 2022-05-06 21:31:29
回答 1查看 54关注 0票数 0

我正在努力使我的日志模式成为我的公司制定的标准,并可能需要一些帮助。我需要从我的应用程序登录到JSON,所以我把扩展LayoutSkeleton的Json布局放在一起

代码语言:javascript
复制
public class JsonLayout : LayoutSkeleton
{

    public override void ActivateOptions()
    {
    }

    public override void Format(TextWriter writer, LoggingEvent e)
    {
        var dic = new Dictionary<string, object>
        {
            ["level"] = e.Level.DisplayName,
            ["message"] = e.MessageObject,
            ["timestampUtc"] = e.TimeStamp.ToUniversalTime().ToString("O"),
            ["userName"] = e.UserName
        };
        writer.WriteLine(JsonConvert.SerializeObject(dic));
    }
}

并在我的app.config中引用如下

代码语言:javascript
复制
    <appender name="file" type="log4net.Appender.RollingFileAppender,log4net">
        <rollingStyle value="Date" />
        <datePattern value="yyyy-MM-dd" />
        <preserveLogFileNameExtension value="true" />
        <staticLogFileName value="false" />
        <file type="log4net.Util.PatternString" value="c:\\Logs\\.log" />
        <layout type="MyPackage.JsonLayout">
        </layout>
    </appender>

然后当我们登录时,很简单:

代码语言:javascript
复制
Dictionary<string, string> logObject = new Dictionary<string, string>
{
   { "systemId", systemId },
   { "workflowId", workflowId },
   { "transitionName", transitionName },
   { "instrumentId", instrumentId },
   { "instrumentName", instrumentName },
   { "commandId", commandId.ToString() },
   { "message", statusMessage }                    
};
Logger.Info(logObject);

这个很管用。然而,最终被记录下来的是

代码语言:javascript
复制
{
"level": "INFO",
"message": {
    "systemId": "LM9125",
    "workflowId": "WF7656789876",
    "transitionName": "My transition",
    "instrumentId": "LM123",
    "instrumentName": "Centrifuge 1",
    "commandId": "d21fb5fa-5b39-4c43-94cc-72dc6a7a174d",
    "message": "Centrifuge 1 started"
},
"timestampUtc": "2022-05-06T20:23:06.5136166Z",
"userName": "labuser"

}

所请求的是,在记录的消息中,我从message对象中删除嵌套,以便log语句变为

代码语言:javascript
复制
{
  "level": "INFO",
  "systemId": "LM9125",
  "workflowId": "WF7656789876",
  "transitionName": "My transition",
  "instrumentId": "LM123",
  "instrumentName": "Centrifuge 1",
  "commandId": "d21fb5fa-5b39-4c43-94cc-72dc6a7a174d",
  "message": "Centrifuge 1 started",
  "timestampUtc": "2022-05-06T20:23:06.5136166Z",
  "userName": "labuser"
}

我已经更新了格式方法

代码语言:javascript
复制
...
var dic = new Dictionary<string, object>
{
   ["level"] = e.Level.DisplayName,
   ["systemId"] = "",
   ["workflowId"] = "",
   ["transitionName"] = "",
   ["instrumentId"] = "",
   ["instrumentName"] = "",
   ["message"] = e.MessageObject,
   ["timestampUtc"] = e.TimeStamp.ToUniversalTime().ToString("O"),
   ["userName"] = e.UserName
 };
 writer.WriteLine(JsonConvert.SerializeObject(dic));
 ...

我似乎想不出的是如何从e.MessageObject中提取值,以便将值放入必要的字段中。在调试器中,我可以看到e.MessageObjectobject {System.Collections.Generic.Dictionary<string, string>}类型的。

当我试图像普通字典一样使用e.MessageObject["systemId"]访问它时,我会得到以下错误消息error CS0021: Cannot apply indexing with [] to an expression of type 'object'。我不是.NET程序员,无法找到解决这个愚蠢错误的方法。请帮帮我!

我搜索了堆栈溢出,找到的最接近的答案是this。但这对解决这个问题毫无帮助。

EN

回答 1

Stack Overflow用户

发布于 2022-05-06 22:57:46

object是一种泛型类型,意思是“我可以在这里存储几乎任何类型的东西”。所以编译器不知道会有哪种类型,所以它拒绝将索引语义应用到它。

你需要让编译器知道你在处理什么样的对象.

与…有关的东西:

代码语言:javascript
复制
Dictionary<string,string> messages = e.MessageObject as Dictionary<string,string>;
if(null == messages) {
    // The thing stored here is NOT a Dictionary<string,string>.
    throw new Exception("not the right type");
}
// code to work with the Dictionary...  messages["systemId"]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72147567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档