tpt_serverless 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79cd51cffa298855dee8d962778a10ff1c10795c84b0eb241b4740cd01729fad
4
- data.tar.gz: 89a61b7b55a6b5d5ef727c55433de43fdec7a7d65e2661b51989ab5019939d11
3
+ metadata.gz: b77f8c69c7659ad042a65c49fd24d10dce69561ad50bb5be5cc1769c10772c04
4
+ data.tar.gz: 9183232aa41d8575f48272ac3b9cd98f0e528e25854380eae93ea05d1d3b8b76
5
5
  SHA512:
6
- metadata.gz: 400d09088658e9c203ac4722d6aefe5cbf3ec51a683f6eee4034a81159719e240ec10e56ffc076f318960302e6de4b0d5f615ad5266dfc1af9cad629d9c70224
7
- data.tar.gz: d7e397fa1ea576adc5cc318192ba8f1bc63fce76c7b74c265b51147d358862358df5ace6c02601c5adcd9d0b12c5a89f322915c75f66bbfad20f0504620b3401
6
+ metadata.gz: 531e07d718df8e8b6d040e088bfad8798f6c259faf47c9cc77ffafee653376c07263e76f075bb65c4ee70ec9f13c44f95bba45026e9275b4ad0c5e39a9cacbd5
7
+ data.tar.gz: 1a08cdd1f3e073bca3517bd617eefb06cf7df36836a3d949f8a4413d794cd55859abd0a7f0032d54d0275b9cf98106eb1439915e3368d8cb00b859e95152e0b7
@@ -0,0 +1,105 @@
1
+ =begin
2
+ Receives logs from CloudWatch and forwards them to Sumologic.
3
+
4
+ Example of how to add this to your `serverless.yml`:
5
+
6
+ forwardLogs:
7
+ name: ${self:service.name}-forwardLogs-${self:provider.stage}
8
+ # NOTE: Ensure that you update the path below if you update the tpt_serverless gem
9
+ handler: /opt/ruby/2.5.0/gems/tpt_serverless-X.X.X/lib/tpt_serverless/sumo_log_forwarder.rb
10
+ timeout: 10 # seconds
11
+ environment:
12
+ SUMO_ENDPOINT: ${self:custom.sumoEndpoint}
13
+ events:
14
+ - cloudwatchLog: /aws/lambda/${self:service.name}-functionOne-${self:provider.stage}
15
+ - cloudwatchLog: /aws/lambda/${self:service.name}-functionTwo-${self:provider.stage}
16
+ …etc…
17
+ reservedConcurrency: ${self:custom.sumoConcurrency}
18
+ =end
19
+
20
+ require 'zlib'
21
+ require 'base64'
22
+
23
+ TIME_REGEX = /^20\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\.\d\d\dZ/
24
+
25
+ # This handler receives CloudWatch log events, parses the events and forwards the extracted logs to
26
+ # Sumo Logic.
27
+ #
28
+ # It performs a few helpful cleanup/prep functions as well.
29
+ def handler(event: , context:)
30
+ sumo_endpoint = ENV['SUMO_ENDPOINT']
31
+
32
+ if sumo_endpoint.nil? || sumo_endpoint.strip.empty?
33
+ puts 'ERROR: SUMO_ENDPOINT is not set. Skipping log forwarding.'
34
+ return
35
+ end
36
+
37
+ sumo_url = URI.parse(sumo_endpoint)
38
+ raw_data = event.fetch('awslogs').fetch('data')
39
+ unzipped_data = Zlib::GzipReader.new(StringIO.new(Base64.decode64(raw_data))).read
40
+ data = JSON.parse(unzipped_data)
41
+
42
+ message_type = data.fetch('messageType')
43
+ log_group = data.fetch('logGroup')
44
+ log_stream = data.fetch('logStream')
45
+ log_events = data.fetch('logEvents')
46
+
47
+ if message_type === 'CONTROL_MESSAGE'
48
+ puts 'skipping control message'
49
+ return
50
+ end
51
+
52
+ puts "message_count=#{log_events.length}"
53
+
54
+ messages_data = extract_messages(log_events).map do |message|
55
+ # AWS replaces newlines with carriage returns in Lambda logs
56
+ message.gsub(/\r(?!\n)/, "\n")
57
+ end.join('')
58
+
59
+ send_to_sumo(sumo_url, log_group, log_stream, messages_data)
60
+ end
61
+
62
+ private
63
+
64
+ def extract_messages(log_events)
65
+ log_events.map do |log_event|
66
+ message = log_event.fetch('message')
67
+ timestamp = Integer(log_event.fetch('timestamp'))
68
+
69
+ # Ensure the message starts with a time.
70
+ # E.g. START/END/REPORT log events don't.
71
+ if TIME_REGEX !~ message
72
+ time_string = Time.at(timestamp/1000.0).utc.strftime('%Y-%m-%dT%H:%M:%S.%LZ')
73
+ message = "#{time_string} #{message}"
74
+ end
75
+
76
+ message
77
+ end
78
+ end
79
+
80
+ def send_to_sumo(sumo_url, log_group, log_stream, data)
81
+ response = Net::HTTP.start(sumo_url.host, sumo_url.port, use_ssl: sumo_url.scheme == 'https') do |http|
82
+ http.open_timeout = 3
83
+ http.read_timeout = 3
84
+
85
+ req = Net::HTTP::Post.new(
86
+ sumo_url,
87
+ {
88
+ 'X-Sumo-Category' => log_group,
89
+ 'X-Sumo-Client' => 'cwl-aws-lambda',
90
+ 'X-Sumo-Host' => log_group,
91
+ 'X-Sumo-Name' => log_stream,
92
+ 'Accept' => 'application/json',
93
+ 'Content-Type' => 'application/json'
94
+ }
95
+ )
96
+
97
+ req.body = data.to_json
98
+
99
+ http.request(req)
100
+ end
101
+
102
+ if response.code != '200'
103
+ response.error!
104
+ end
105
+ end
@@ -1,3 +1,3 @@
1
1
  module TptServerless
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tpt_serverless
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TpT
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-23 00:00:00.000000000 Z
11
+ date: 2020-02-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -17,6 +17,7 @@ extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
19
  - lib/tpt_serverless.rb
20
+ - lib/tpt_serverless/sumo_log_forwarder.rb
20
21
  - lib/tpt_serverless/version.rb
21
22
  homepage: https://github.com/TeachersPayTeachers/tpt_serverless-ruby
22
23
  licenses: []