tpt_serverless 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/tpt_serverless/datadog_log_forwarder.rb +46 -12
- data/lib/tpt_serverless/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c1f06b4fad5f9e34e05e818977304236568122d0a604ecd88e8cf6da4b331d5a
|
|
4
|
+
data.tar.gz: 2b54c154a4457028ed90778f699aa159acef24ba4abe6d40f01f80deb0926393
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bec09d6328b91ac709832540773484e01773d2da113166b592aea0cf2070823d69376bf32b5bf442cf5cbb9e367fda385bf7fdb62774d8c716b6de28faf97507
|
|
7
|
+
data.tar.gz: 91f0d1ce2681a15b8a5602cfa3736a700e79ab5016e4c9c542fb81dd250da2e98a0c351cf295515f61549bf4746471a84c4ef107ca6a4a00ce361536cdc03e23
|
|
@@ -15,6 +15,11 @@ Example of how to add this to your `serverless.yml`:
|
|
|
15
15
|
DATADOG_SOURCE: cwl-aws-lambda # default
|
|
16
16
|
DATADOG_SERVICE: ${self:service.name} # optional
|
|
17
17
|
DATADOG_TAGS: stage:${self:provider.stage},team:platform # optional
|
|
18
|
+
# If set to a truthy value (1, true, yes, or on; case/whitespace-insensitive),
|
|
19
|
+
# filters AWS Lambda platform lifecycle boilerplate logs like
|
|
20
|
+
# INIT_START / START / END / REPORT before forwarding to Datadog.
|
|
21
|
+
# Defaults to false.
|
|
22
|
+
DATADOG_FILTER_LIFECYCLE_LOGS: "true" # optional
|
|
18
23
|
events:
|
|
19
24
|
- cloudwatchLog: /aws/lambda/${self:service.name}-functionOne-${self:provider.stage}
|
|
20
25
|
- cloudwatchLog: /aws/lambda/${self:service.name}-functionTwo-${self:provider.stage}
|
|
@@ -31,6 +36,9 @@ require 'uri'
|
|
|
31
36
|
class DatadogLogForwarder
|
|
32
37
|
TIME_REGEX ||= /^20\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\.\d\d\dZ/
|
|
33
38
|
|
|
39
|
+
# Matches AWS Lambda platform lifecycle lines that are usually noisy in Datadog
|
|
40
|
+
LAMBDA_LIFECYCLE_AFTER_TIMESTAMP_REGEX ||= /\A(?:INIT_START\b|START RequestId:|END RequestId:|REPORT RequestId:)/
|
|
41
|
+
|
|
34
42
|
class << self
|
|
35
43
|
# This handler receives CloudWatch log events, parses the events and forwards the extracted logs to
|
|
36
44
|
# Datadog.
|
|
@@ -58,7 +66,16 @@ class DatadogLogForwarder
|
|
|
58
66
|
return
|
|
59
67
|
end
|
|
60
68
|
|
|
61
|
-
|
|
69
|
+
normalized_log_events = normalize_messages(log_events)
|
|
70
|
+
|
|
71
|
+
filtered_log_events =
|
|
72
|
+
if should_filter_lifecycle_logs?
|
|
73
|
+
normalized_log_events.reject { |e| lambda_lifecycle_line?(e[:message]) }
|
|
74
|
+
else
|
|
75
|
+
normalized_log_events
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
puts "message_count=#{log_events.length} forwarded_count=#{filtered_log_events.length}"
|
|
62
79
|
|
|
63
80
|
region = 'unknown'
|
|
64
81
|
account_id = 'unknown'
|
|
@@ -72,11 +89,9 @@ class DatadogLogForwarder
|
|
|
72
89
|
function_name = log_group&.split('/')&.last
|
|
73
90
|
function_arn = "arn:aws:lambda:#{region}:#{account_id}:function:#{function_name}"
|
|
74
91
|
|
|
75
|
-
normalized_data =
|
|
76
|
-
normalized_msg = normalize_messages([log_event]).first
|
|
77
|
-
|
|
92
|
+
normalized_data = filtered_log_events.map do |log_event|
|
|
78
93
|
{
|
|
79
|
-
message:
|
|
94
|
+
message: log_event[:message],
|
|
80
95
|
ddsource: ENV['DATADOG_SOURCE'] || 'cwl-aws-lambda',
|
|
81
96
|
service: ENV['DATADOG_SERVICE'] || function_name,
|
|
82
97
|
hostname: function_arn,
|
|
@@ -87,10 +102,13 @@ class DatadogLogForwarder
|
|
|
87
102
|
logStream: log_stream
|
|
88
103
|
}
|
|
89
104
|
},
|
|
90
|
-
id: log_event[
|
|
105
|
+
id: log_event[:id]
|
|
91
106
|
}
|
|
92
107
|
end
|
|
93
108
|
|
|
109
|
+
# If we filtered everything out, do nothing.
|
|
110
|
+
return if normalized_data.empty?
|
|
111
|
+
|
|
94
112
|
begin
|
|
95
113
|
send_json_to_datadog(normalized_data.to_json)
|
|
96
114
|
puts "Datadog upload successful: sent #{normalized_data.length} log(s) for #{function_name}"
|
|
@@ -106,21 +124,38 @@ class DatadogLogForwarder
|
|
|
106
124
|
|
|
107
125
|
def normalize_messages(log_events)
|
|
108
126
|
log_events.map do |log_event|
|
|
127
|
+
id = log_event.fetch('id')
|
|
109
128
|
message = log_event.fetch('message')
|
|
110
|
-
|
|
129
|
+
timestamp_ms = Integer(log_event.fetch('timestamp'))
|
|
111
130
|
|
|
112
|
-
# Ensure the message starts with
|
|
113
|
-
# E.g. START/END/REPORT log events don't.
|
|
131
|
+
# Ensure the message starts with an ISO timestamp (same intent as Node)
|
|
114
132
|
if TIME_REGEX !~ message
|
|
115
|
-
time_string = Time.at(
|
|
133
|
+
time_string = Time.at(timestamp_ms / 1000.0).utc.strftime('%Y-%m-%dT%H:%M:%S.%LZ')
|
|
116
134
|
message = "#{time_string} #{message}"
|
|
117
135
|
end
|
|
118
136
|
|
|
119
137
|
# AWS replaces newlines with carriage returns in Lambda logs
|
|
120
|
-
message.gsub(/\r(?!\n)/, "\n")
|
|
138
|
+
message = message.gsub(/\r(?!\n)/, "\n")
|
|
139
|
+
|
|
140
|
+
{ id: id, message: message }
|
|
121
141
|
end
|
|
122
142
|
end
|
|
123
143
|
|
|
144
|
+
def should_filter_lifecycle_logs?
|
|
145
|
+
truthy_env?(ENV['DATADOG_FILTER_LIFECYCLE_LOGS'])
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def truthy_env?(value)
|
|
149
|
+
return false if value.nil?
|
|
150
|
+
%w[1 true yes on].include?(value.strip.downcase)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def lambda_lifecycle_line?(message_with_timestamp)
|
|
154
|
+
# Strip the leading ISO timestamp and match on the remainder.
|
|
155
|
+
after_timestamp = message_with_timestamp.sub(TIME_REGEX, '').lstrip
|
|
156
|
+
LAMBDA_LIFECYCLE_AFTER_TIMESTAMP_REGEX.match?(after_timestamp)
|
|
157
|
+
end
|
|
158
|
+
|
|
124
159
|
def send_json_to_datadog(data)
|
|
125
160
|
datadog_site = ENV['DATADOG_SITE'] || 'datadoghq.com'
|
|
126
161
|
datadog_url = URI("https://http-intake.logs.#{datadog_site}/api/v2/logs")
|
|
@@ -138,7 +173,6 @@ class DatadogLogForwarder
|
|
|
138
173
|
)
|
|
139
174
|
|
|
140
175
|
req.body = data
|
|
141
|
-
|
|
142
176
|
http.request(req)
|
|
143
177
|
end
|
|
144
178
|
|