Skip to content

Commit 76ec59c

Browse files
committed
fix: 优化日志扩展属性
1 parent 85c1fc5 commit 76ec59c

File tree

12 files changed

+467
-15
lines changed

12 files changed

+467
-15
lines changed

framework/src/Bing.Logging.Sinks.Exceptionless/Serilog/Sinks/Exceptionless/ExceptionlessSink.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using Bing;
5+
using Bing.Logging.ExtraSupports;
46
using Bing.Logging.Sinks.Exceptionless.Internals;
57
using Exceptionless;
68
using Exceptionless.Dependency;
@@ -130,10 +132,20 @@ public void Emit(LogEvent logEvent)
130132
builder.SetUserDescription(emailAddress, description);
131133
break;
132134
case "Tags" when property.Value is SequenceValue tags:
133-
var tagList = tags.FlattenProperties() as List<object>;
134-
if(tagList is null)
135-
continue;
136-
builder.AddTags(tagList.Select(x=>x.ToString()).ToArray());
135+
{
136+
var tagList = tags.FlattenProperties() as List<object>;
137+
if (tagList is null)
138+
continue;
139+
builder.AddTags(tagList.Select(x => x.ToString()).ToArray());
140+
}
141+
break;
142+
case ContextDataTypes.Tags when property.Value is SequenceValue tags:
143+
{
144+
var tagList = tags.FlattenProperties() as List<object>;
145+
if (tagList is null)
146+
continue;
147+
builder.AddTags(tagList.Select(x => x.ToString()).ToArray());
148+
}
137149
break;
138150
default:
139151
builder.SetProperty(property.Key, property.Value.FlattenProperties());
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using Bing.Logging.ExtraSupports;
4+
5+
namespace Bing.Logging.Core
6+
{
7+
/// <summary>
8+
/// 日志事件上下文
9+
/// </summary>
10+
public class LogEventContext
11+
{
12+
#region Tags(标签列表)
13+
14+
/// <summary>
15+
/// 标签列表
16+
/// </summary>
17+
private readonly List<string> _tags = new List<string>();
18+
19+
/// <summary>
20+
/// 标签列表
21+
/// </summary>
22+
internal IReadOnlyList<string> Tags => _tags;
23+
24+
/// <summary>
25+
/// 设置标签列表
26+
/// </summary>
27+
/// <param name="tags">标签列表</param>
28+
public LogEventContext SetTags(params string[] tags)
29+
{
30+
if (tags == null)
31+
return this;
32+
foreach (var tag in tags)
33+
{
34+
if (string.IsNullOrWhiteSpace(tag))
35+
continue;
36+
if (_tags.Contains(tag))
37+
continue;
38+
_tags.Add(tag);
39+
}
40+
return this;
41+
}
42+
43+
#endregion
44+
45+
#region Parameters(参数列表)
46+
47+
/// <summary>
48+
/// 参数列表
49+
/// </summary>
50+
private readonly List<object> _parameters = new List<object>();
51+
52+
/// <summary>
53+
/// 设置参数
54+
/// </summary>
55+
/// <param name="parameter">参数</param>
56+
public LogEventContext SetParameter(object parameter)
57+
{
58+
if (parameter == null)
59+
return this;
60+
_parameters.Add(parameter);
61+
return this;
62+
}
63+
64+
/// <summary>
65+
/// 设置参数列表
66+
/// </summary>
67+
/// <param name="parameters">参数列表</param>
68+
public LogEventContext SetParameters(params object[] parameters)
69+
{
70+
foreach (var parameter in parameters)
71+
SetParameter(parameter);
72+
return this;
73+
}
74+
75+
/// <summary>
76+
/// 参数列表
77+
/// </summary>
78+
internal IReadOnlyList<object> Parameters => _parameters;
79+
80+
#endregion
81+
82+
#region ExtraProperties(扩展属性)
83+
84+
/// <summary>
85+
/// 扩展属性
86+
/// </summary>
87+
private readonly ContextData _extraProperties = new ContextData();
88+
89+
/// <summary>
90+
/// 设置扩展属性
91+
/// </summary>
92+
/// <param name="name">名称</param>
93+
/// <param name="value">值</param>
94+
public LogEventContext SetExtraProperty(string name, object value)
95+
{
96+
if (string.IsNullOrWhiteSpace(name))
97+
return this;
98+
_extraProperties.AddOrUpdateItem($"{ContextDataTypes.ExtraProperty}_{name}", value, false);
99+
return this;
100+
}
101+
102+
/// <summary>
103+
/// 扩展属性
104+
/// </summary>
105+
public ContextData ExtraProperties => _extraProperties;
106+
107+
#endregion
108+
109+
#region ExposeScopeState(公开作用域状态)
110+
111+
/// <summary>
112+
/// 公开作用域状态
113+
/// </summary>
114+
public IDictionary<string, object> ExposeScopeState()
115+
{
116+
var dict = new Dictionary<string, object>();
117+
if (Tags.Any())
118+
dict[ContextDataTypes.Tags] = Tags;
119+
if (ExtraProperties.Any())
120+
{
121+
foreach (var kvp in ExtraProperties)
122+
dict.Add(kvp.Key, kvp.Value.Value);
123+
}
124+
return dict;
125+
}
126+
127+
#endregion
128+
}
129+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace Bing.Logging.Core
2+
{
3+
/// <summary>
4+
/// 日志事件描述符
5+
/// </summary>
6+
public class LogEventDescriptor
7+
{
8+
/// <summary>
9+
/// 初始化一个<see cref="LogEventDescriptor"/>类型的实例
10+
/// </summary>
11+
public LogEventDescriptor()
12+
{
13+
Context = new LogEventContext();
14+
}
15+
16+
/// <summary>
17+
/// 日志事件上下文
18+
/// </summary>
19+
public LogEventContext Context { get; }
20+
}
21+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Bing.Logging.ExtraSupports
6+
{
7+
/// <summary>
8+
/// 日志事件上下文数据
9+
/// </summary>
10+
public class ContextData : Dictionary<string, ContextDataItem>
11+
{
12+
/// <summary>
13+
/// 初始化一个<see cref="ContextData"/>类型的实例
14+
/// </summary>
15+
public ContextData() : base(StringComparer.OrdinalIgnoreCase) { }
16+
17+
/// <summary>
18+
/// 初始化一个<see cref="ContextData"/>类型的实例
19+
/// </summary>
20+
/// <param name="ctx">字典</param>
21+
public ContextData(IDictionary<string, ContextDataItem> ctx) : base(ctx, StringComparer.OrdinalIgnoreCase) { }
22+
23+
/// <summary>
24+
/// 添加项
25+
/// </summary>
26+
/// <param name="name">名称</param>
27+
/// <param name="value">值</param>
28+
/// <param name="output">是否输出</param>
29+
/// <exception cref="ArgumentNullException"></exception>
30+
public void AddItem(string name, object value, bool output = true)
31+
{
32+
if (ContainsKey(name))
33+
throw new ArgumentException($"Key '{name}' has been added.", nameof(name));
34+
if (value is ContextDataItem item)
35+
Add(item.Name, item);
36+
else
37+
Add(name, new ContextDataItem(name, value.GetType(), value, output));
38+
}
39+
40+
/// <summary>
41+
/// 添加或更新项
42+
/// </summary>
43+
/// <param name="name">名称</param>
44+
/// <param name="value">值</param>
45+
/// <param name="output">是否输出</param>
46+
public void AddOrUpdateItem(string name, object value, bool output = true)
47+
{
48+
if (value is ContextDataItem item)
49+
AddOrUpdateInternal(item.Name, item);
50+
else
51+
AddOrUpdateInternal(name, new ContextDataItem(name, value.GetType(), value, output));
52+
}
53+
54+
/// <summary>
55+
/// 添加或更新
56+
/// </summary>
57+
/// <param name="name">名称</param>
58+
/// <param name="item">项</param>
59+
private void AddOrUpdateInternal(string name, ContextDataItem item)
60+
{
61+
if (ContainsKey(name))
62+
this[name] = item;
63+
else
64+
Add(name, item);
65+
}
66+
67+
/// <summary>
68+
/// 当前上游上下文数据的指针
69+
/// </summary>
70+
private ContextData CurrentUpstreamContextPointer { get; set; }
71+
72+
/// <summary>
73+
/// 导入上游的上下文数据
74+
/// </summary>
75+
/// <param name="contextData">日志事件上下文数据</param>
76+
internal void ImportUpstreamContextData(ContextData contextData)
77+
{
78+
if (contextData == null)
79+
return;
80+
CurrentUpstreamContextPointer = contextData;
81+
foreach (var data in contextData)
82+
{
83+
if (ContainsKey(data.Key))
84+
continue;
85+
Add(data.Key, data.Value);
86+
}
87+
}
88+
89+
/// <summary>
90+
/// 导出上游的上下文数据
91+
/// </summary>
92+
internal ContextData ExportUpstreamContextData() => CurrentUpstreamContextPointer;
93+
94+
/// <summary>
95+
/// 输出字符串
96+
/// </summary>
97+
public override string ToString()
98+
{
99+
if (Count == 0)
100+
return string.Empty;
101+
var sb = new StringBuilder();
102+
var fen = "";
103+
sb.Append("[");
104+
foreach (var item in this)
105+
{
106+
if (!item.Value.Output)
107+
continue;
108+
sb.Append(fen);
109+
fen = ",";
110+
sb.Append($"{{\"{item.Key}\":\"{item.Value}\"}}");
111+
}
112+
sb.Append("]");
113+
return sb.ToString();
114+
}
115+
116+
/// <summary>
117+
/// 克隆
118+
/// </summary>
119+
public ContextData Copy() => new(this);
120+
}
121+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System;
2+
using System.Text;
3+
4+
namespace Bing.Logging.ExtraSupports
5+
{
6+
/// <summary>
7+
/// 日志事件上下文数据项
8+
/// </summary>
9+
public class ContextDataItem
10+
{
11+
/// <summary>
12+
/// 初始化一个<see cref="ContextDataItem"/>类型的实例
13+
/// </summary>
14+
/// <param name="name">名称</param>
15+
/// <param name="type">类型</param>
16+
/// <param name="value">值</param>
17+
/// <param name="output">是否输出</param>
18+
public ContextDataItem(string name, Type type, object value, bool output = true)
19+
{
20+
ItemType = type;
21+
Value = value;
22+
Name = name;
23+
Output = output;
24+
}
25+
26+
/// <summary>
27+
/// 名称
28+
/// </summary>
29+
public string Name { get; }
30+
31+
/// <summary>
32+
/// 类型
33+
/// </summary>
34+
public Type ItemType { get; }
35+
36+
/// <summary>
37+
/// 值
38+
/// </summary>
39+
public object Value { get; }
40+
41+
/// <summary>
42+
/// 是否输出
43+
/// </summary>
44+
public bool Output { get; }
45+
46+
/// <inheritdoc />
47+
public override string ToString()
48+
{
49+
var sb = new StringBuilder();
50+
sb.Append("{");
51+
sb.Append($"\"Name\":\"{Name}\",");
52+
sb.Append($"\"Type\":\"{ItemType}\",");
53+
sb.Append($"\"Value\":\"{Value}\"");
54+
sb.Append("}");
55+
return sb.ToString();
56+
}
57+
}
58+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace Bing.Logging.ExtraSupports
2+
{
3+
/// <summary>
4+
/// 日志事件上下文数据类型
5+
/// </summary>
6+
public class ContextDataTypes
7+
{
8+
/// <summary>
9+
/// 扩展属性
10+
/// </summary>
11+
public const string ExtraProperty = "__BING_EXTRA_PROPERTY";
12+
13+
/// <summary>
14+
/// 扩展属性
15+
/// </summary>
16+
public const string Tags = "__BING_TAGS";
17+
}
18+
}

0 commit comments

Comments
 (0)