logstash @timestamp 到 .NET 中强类型的弹性搜索映射
Elastic Search mapping of logstash @timestamp to strongly typed in .NET
我使用 Serilog 和 ElasticSearch Sink,AutoRegisterTemplate = true
在 ElasticSearch 中存储以下内容
{
"@timestamp": "2016-08-17T08:57:37.3487446+02:00",
"level": "Information",
"messageTemplate": "User login {UserId}",
"message": "User login ...,
"fields": {
"UserId": "...",
"ProcessId": 15568,
"ThreadId": 14,
"MachineName": "...",
"EnvironmentUserName": "...",
"HttpRequestId": "...",
"HttpRequestClientHostIP": "::1",
"HttpRequestType": "POST",
"Version": "1.0.0.0"
}
}
我可以用 DynamicResponse 查询索引
var searchResponse = client.Search<DynamicResponse>(s => s
.Index("logstash-*")
.AllTypes()
.Size(50)
.Query(q => q.Bool(b => b.Must(bs => bs.Term(p => p.Field("fields.UserId.raw").Value("..."))))
)
);
但我想对结果使用强类型 class。
我试过以下class。
public class LogResponse
{
public string Message { get; set; }
[Date(Name = "@timestamp")]
public DateTime Timestamp { get; set; }
public LogResponseFields Fields { get; set; }
public class LogResponseFields
{
public Guid UserId { get; set; }
}
}
但是没有设置时间戳,默认为DateTime.Min,Message和UserId都映射正确
如何映射@timestamp 字段?
尝试 DateTimeOffset
这似乎是一个带有嵌入式时区信息的时间戳。 (+02:00
具体)
时间戳字段的映射工作正常;这里有一个完整的例子来演示
void Main()
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var defaultIndex = "logstash-" + DateTime.UtcNow.ToString("yyyy-MM-dd");
var connectionSettings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex)
.InferMappingFor<LogResponse>(m => m
.TypeName("log")
);
var client = new ElasticClient(connectionSettings);
// delete the index if it exists. Useful for demo purposes
if (client.IndexExists(defaultIndex).Exists)
{
client.DeleteIndex(defaultIndex);
}
// use the lowlevel client to send the exact json as
// it would be sent from the source
var createResponse = client.LowLevel.Index<string>(
defaultIndex,
"log",
@"{
""@timestamp"": ""2016-08-17T08:57:37.3487446+02:00"",
""level"": ""Information"",
""messageTemplate"": ""User login {UserId}"",
""message"": ""User login .."",
""fields"": {
""UserId"": ""29a35806-15d2-4eed-a3bf-707760e426b8"",
""ProcessId"": 15568,
""ThreadId"": 14,
""MachineName"": ""..."",
""EnvironmentUserName"": ""..."",
""HttpRequestId"": ""..."",
""HttpRequestClientHostIP"": ""::1"",
""HttpRequestType"": ""POST"",
""Version"": ""1.0.0.0""
}
}");
if (!createResponse.SuccessOrKnownError)
{
Console.WriteLine("Error indexing document");
}
// Refresh the index after indexing. Useful for demo purposes.
client.Refresh(defaultIndex);
var searchResponse = client.Search<LogResponse>(s => s
.AllTypes()
.Size(50)
.Query(q => q
.MatchAll()
)
);
foreach (var document in searchResponse.Documents)
{
Console.WriteLine(document.Timestamp);
}
}
public class LogResponse
{
public string Message { get; set; }
[Date(Name = "@timestamp")]
public DateTime Timestamp { get; set; }
public LogResponseFields Fields { get; set; }
public class LogResponseFields
{
public Guid UserId { get; set; }
}
}
这输出
17/08/2016 4:57:37 PM
对我来说(它已经被反序列化到我的本地DateTime
)。
感谢您的输入。
当我将示例 post 改为 SO 时,问题已解决。
我的真实代码是:
public class LogResponse : DynamicResponse
所以通过删除 DynamicResponse 继承
public class LogResponse
一切正常。
我使用 Serilog 和 ElasticSearch Sink,AutoRegisterTemplate = true
在 ElasticSearch 中存储以下内容
{
"@timestamp": "2016-08-17T08:57:37.3487446+02:00",
"level": "Information",
"messageTemplate": "User login {UserId}",
"message": "User login ...,
"fields": {
"UserId": "...",
"ProcessId": 15568,
"ThreadId": 14,
"MachineName": "...",
"EnvironmentUserName": "...",
"HttpRequestId": "...",
"HttpRequestClientHostIP": "::1",
"HttpRequestType": "POST",
"Version": "1.0.0.0"
}
}
我可以用 DynamicResponse 查询索引
var searchResponse = client.Search<DynamicResponse>(s => s
.Index("logstash-*")
.AllTypes()
.Size(50)
.Query(q => q.Bool(b => b.Must(bs => bs.Term(p => p.Field("fields.UserId.raw").Value("..."))))
)
);
但我想对结果使用强类型 class。
我试过以下class。
public class LogResponse
{
public string Message { get; set; }
[Date(Name = "@timestamp")]
public DateTime Timestamp { get; set; }
public LogResponseFields Fields { get; set; }
public class LogResponseFields
{
public Guid UserId { get; set; }
}
}
但是没有设置时间戳,默认为DateTime.Min,Message和UserId都映射正确
如何映射@timestamp 字段?
尝试 DateTimeOffset
这似乎是一个带有嵌入式时区信息的时间戳。 (+02:00
具体)
时间戳字段的映射工作正常;这里有一个完整的例子来演示
void Main()
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var defaultIndex = "logstash-" + DateTime.UtcNow.ToString("yyyy-MM-dd");
var connectionSettings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex)
.InferMappingFor<LogResponse>(m => m
.TypeName("log")
);
var client = new ElasticClient(connectionSettings);
// delete the index if it exists. Useful for demo purposes
if (client.IndexExists(defaultIndex).Exists)
{
client.DeleteIndex(defaultIndex);
}
// use the lowlevel client to send the exact json as
// it would be sent from the source
var createResponse = client.LowLevel.Index<string>(
defaultIndex,
"log",
@"{
""@timestamp"": ""2016-08-17T08:57:37.3487446+02:00"",
""level"": ""Information"",
""messageTemplate"": ""User login {UserId}"",
""message"": ""User login .."",
""fields"": {
""UserId"": ""29a35806-15d2-4eed-a3bf-707760e426b8"",
""ProcessId"": 15568,
""ThreadId"": 14,
""MachineName"": ""..."",
""EnvironmentUserName"": ""..."",
""HttpRequestId"": ""..."",
""HttpRequestClientHostIP"": ""::1"",
""HttpRequestType"": ""POST"",
""Version"": ""1.0.0.0""
}
}");
if (!createResponse.SuccessOrKnownError)
{
Console.WriteLine("Error indexing document");
}
// Refresh the index after indexing. Useful for demo purposes.
client.Refresh(defaultIndex);
var searchResponse = client.Search<LogResponse>(s => s
.AllTypes()
.Size(50)
.Query(q => q
.MatchAll()
)
);
foreach (var document in searchResponse.Documents)
{
Console.WriteLine(document.Timestamp);
}
}
public class LogResponse
{
public string Message { get; set; }
[Date(Name = "@timestamp")]
public DateTime Timestamp { get; set; }
public LogResponseFields Fields { get; set; }
public class LogResponseFields
{
public Guid UserId { get; set; }
}
}
这输出
17/08/2016 4:57:37 PM
对我来说(它已经被反序列化到我的本地DateTime
)。
感谢您的输入。
当我将示例 post 改为 SO 时,问题已解决。
我的真实代码是:
public class LogResponse : DynamicResponse
所以通过删除 DynamicResponse 继承
public class LogResponse
一切正常。