10
10
# [source,ruby]
11
11
# input {
12
12
# tcp {
13
- # codec => fluent
13
+ # codec => fluent {
14
+ # nanosecond_precision => true
15
+ # }
14
16
# port => 4000
15
17
# }
16
18
# }
22
24
#
23
25
# Notes:
24
26
#
25
- # * the fluent uses a second-precision time for events, so you will never see
26
- # subsecond precision on events processed by this codec.
27
+ # * to handle EventTime msgpack extension, you must specify nanosecond_precision parameter as true.
27
28
#
28
29
class LogStash ::Codecs ::Fluent < LogStash ::Codecs ::Base
30
+ require "logstash/codecs/fluent/event_time"
31
+
29
32
config_name "fluent"
30
33
34
+ config :nanosecond_precision , :validate => :boolean , :default => false
35
+
31
36
def register
32
37
require "msgpack"
33
- @decoder = MessagePack ::Unpacker . new
38
+ @factory = MessagePack ::Factory . new
39
+ if @nanosecond_precision
40
+ @factory . register_type ( EventTime ::TYPE , EventTime )
41
+ end
42
+ @packer = @factory . packer
43
+ @decoder = @factory . unpacker
34
44
end
35
45
36
46
def decode ( data , &block )
@@ -43,14 +53,19 @@ def encode(event)
43
53
# Ensure tag to "tag1.tag2.tag3" style string.
44
54
# Fluentd cannot handle Array class value in forward protocol's tag.
45
55
tag = forwardable_tag ( event )
46
- epochtime = event . timestamp . to_i
56
+ epochtime = if @nanosecond_precision
57
+ EventTime . new ( event . timestamp . to_i , event . timestamp . usec * 1000 )
58
+ else
59
+ event . timestamp . to_i
60
+ end
47
61
48
62
# use normalize to make sure returned Hash is pure Ruby for
49
63
# MessagePack#pack which relies on pure Ruby object recognition
50
64
data = LogStash ::Util . normalize ( event . to_hash )
51
65
# timestamp is serialized as a iso8601 string
52
66
# merge to avoid modifying data which could have side effects if multiple outputs
53
- @on_event . call ( event , MessagePack . pack ( [ tag , epochtime , data . merge ( LogStash ::Event ::TIMESTAMP => event . timestamp . to_iso8601 ) ] ) )
67
+ @packer . clear
68
+ @on_event . call ( event , @packer . pack ( [ tag , epochtime , data . merge ( LogStash ::Event ::TIMESTAMP => event . timestamp . to_iso8601 ) ] ) )
54
69
end # def encode
55
70
56
71
def forwardable_tag ( event )
@@ -67,6 +82,15 @@ def forwardable_tag(event)
67
82
68
83
private
69
84
85
+ def decode_fluent_time ( fluent_time )
86
+ case fluent_time
87
+ when Fixnum
88
+ fluent_time
89
+ when EventTime
90
+ Time . at ( fluent_time . sec , fluent_time . nsec )
91
+ end
92
+ end
93
+
70
94
def decode_event ( data , &block )
71
95
tag = data [ 0 ]
72
96
entries = data [ 1 ]
@@ -80,9 +104,9 @@ def decode_event(data, &block)
80
104
raise ( LogStash ::Error , "PackedForward with compression is not supported" )
81
105
end
82
106
83
- entries_decoder = MessagePack :: Unpacker . new
107
+ entries_decoder = @decoder
84
108
entries_decoder . feed_each ( entries ) do |entry |
85
- epochtime = entry [ 0 ]
109
+ epochtime = decode_fluent_time ( entry [ 0 ] )
86
110
map = entry [ 1 ]
87
111
event = LogStash ::Event . new ( map . merge (
88
112
LogStash ::Event ::TIMESTAMP => LogStash ::Timestamp . at ( epochtime ) ,
@@ -93,17 +117,17 @@ def decode_event(data, &block)
93
117
when Array
94
118
# Forward
95
119
entries . each do |entry |
96
- epochtime = entry [ 0 ]
120
+ epochtime = decode_fluent_time ( entry [ 0 ] )
97
121
map = entry [ 1 ]
98
122
event = LogStash ::Event . new ( map . merge (
99
123
LogStash ::Event ::TIMESTAMP => LogStash ::Timestamp . at ( epochtime ) ,
100
124
"tags" => [ tag ]
101
125
) )
102
126
yield event
103
127
end
104
- when Fixnum
128
+ when Fixnum , EventTime
105
129
# Message
106
- epochtime = entries
130
+ epochtime = decode_fluent_time ( entries )
107
131
map = data [ 2 ]
108
132
event = LogStash ::Event . new ( map . merge (
109
133
LogStash ::Event ::TIMESTAMP => LogStash ::Timestamp . at ( epochtime ) ,
0 commit comments