-
Notifications
You must be signed in to change notification settings - Fork 72
Expand file tree
/
Copy pathUlsTypeMap.cs
More file actions
108 lines (92 loc) · 3.91 KB
/
UlsTypeMap.cs
File metadata and controls
108 lines (92 loc) · 3.91 KB
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Reactive;
using System.Linq.Expressions;
using System.Reflection;
namespace UlsLogs
{
class UlsTypeMap : IPartitionableTypeMap<UlsRecord, string>
{
Dictionary<Type, Regex> _expressions = new Dictionary<Type, Regex>();
public IEqualityComparer<string> Comparer
{
get { return StringComparer.Ordinal; }
}
public string GetInputKey(UlsRecord evt)
{
return evt.EventId;
}
public string GetTypeKey(Type outpuType)
{
var eventAttribute = outpuType.GetCustomAttribute<UlsEventAttribute>();
if (eventAttribute == null)
return null;
return eventAttribute.EventId;
}
public Func<UlsRecord, DateTimeOffset> TimeFunction
{
get { return evt => evt.Time; }
}
public Func<UlsRecord, object> GetTransform(Type outputType)
{
var eventAttribute = outputType.GetCustomAttribute<UlsEventAttribute>();
Regex parse = new Regex(eventAttribute.RegEx);
_expressions.Add(outputType, parse);
//Func<UlsRecord, object> example = e =>
// Transform(e, m=>
// new LeavingMonitoredScope
// {
// Scope = m.Groups[1].Value,
// ExecutionTime = double.Parse(m.Groups[2].Value)
// });
//Expression<Func<UlsRecord, object>> example = e =>
// Transform(e, m =>
// new EnteringMonitoredScope
// {
// Scope = m.Groups[1].Value,
// });
var inputEvent = Expression.Parameter(typeof(UlsRecord), "e");
var match = Expression.Parameter(typeof(Match), "m");
List<MemberBinding> bindings = new List<MemberBinding>();
int index = 1;
foreach (FieldInfo field in outputType.GetFields())
{
var value = Expression.Property(
Expression.Call(
Expression.Property(match, typeof(Match).GetProperty("Groups")),
typeof(GroupCollection).GetMethod("get_Item", new Type[]{ typeof(int) }),
Expression.Constant(index++)),
"Value");
if (field.FieldType == typeof(string))
{
var b = Expression.Bind(field, value);
bindings.Add(b);
}
else
{
var p = Expression.Call(field.FieldType.GetMethod("Parse", new Type[]{ typeof(string)}), value);
bindings.Add(Expression.Bind(field, p));
}
}
var n = Expression.New(outputType);
var m = Expression.MemberInit(n, bindings.ToArray());
var lambda2 = Expression.Lambda(m,match);
var transform = this.GetType().GetMethod("Transform", BindingFlags.NonPublic | BindingFlags.Instance);
var trOutput = transform.MakeGenericMethod(outputType);
var call = Expression.Call(Expression.Constant(this), trOutput, inputEvent, lambda2);
var exp = Expression.Lambda<Func<UlsRecord, object>>(call, inputEvent);
return exp.Compile();
}
object Transform<TOutput>(UlsRecord input, Func<Match, TOutput> create)
{
Regex r = _expressions[typeof(TOutput)];
Match m = r.Match(input.Message);
TOutput o = create(m);
return o;
}
}
}