signalfx-lambda 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/Gemfile +6 -0
- data/LICENSE +201 -0
- data/README.md +118 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/signalfx/lambda/tracing/extractors.rb +65 -0
- data/lib/signalfx/lambda/tracing.rb +111 -0
- data/lib/signalfx/lambda/version.rb +5 -0
- data/lib/signalfx/lambda.rb +2 -0
- data/signalfx-lambda.gemspec +29 -0
- metadata +112 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b7d5d079150c49b6b3b43e8a457cc5b4165ffe38e58dfa884a47f49f0a39bf6c
|
4
|
+
data.tar.gz: ccd63f18a2caaf898bc40ce792930adc896e952a62a368730c40c6aa2e08f414
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c9af39140b055a4e4cb7728786b1c4a7de991b517e5302f448ccceadb165d3c32152a69817e1d978c4bb87e6ac6a38a01116c35495f228d97cb1e9b953b70686
|
7
|
+
data.tar.gz: 7cb0f4ffe5863e00e2c63eec53d621f7c1c526eb20318534a0c56d0fee338a3aeb22ba8b2afce900585ab38dbf59f7e82e3a964634a5ea5c22bb097b5169fea6
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
Apache License
|
2
|
+
Version 2.0, January 2004
|
3
|
+
http://www.apache.org/licenses/
|
4
|
+
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
6
|
+
|
7
|
+
1. Definitions.
|
8
|
+
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
11
|
+
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
13
|
+
the copyright owner that is granting the License.
|
14
|
+
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
16
|
+
other entities that control, are controlled by, or are under common
|
17
|
+
control with that entity. For the purposes of this definition,
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
19
|
+
direction or management of such entity, whether by contract or
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
22
|
+
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
24
|
+
exercising permissions granted by this License.
|
25
|
+
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
27
|
+
including but not limited to software source code, documentation
|
28
|
+
source, and configuration files.
|
29
|
+
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
31
|
+
transformation or translation of a Source form, including but
|
32
|
+
not limited to compiled object code, generated documentation,
|
33
|
+
and conversions to other media types.
|
34
|
+
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
36
|
+
Object form, made available under the License, as indicated by a
|
37
|
+
copyright notice that is included in or attached to the work
|
38
|
+
(an example is provided in the Appendix below).
|
39
|
+
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
46
|
+
the Work and Derivative Works thereof.
|
47
|
+
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
49
|
+
the original version of the Work and any modifications or additions
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
61
|
+
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
64
|
+
subsequently incorporated within the Work.
|
65
|
+
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
72
|
+
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
78
|
+
where such license applies only to those patent claims licensable
|
79
|
+
by such Contributor that are necessarily infringed by their
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
82
|
+
institute patent litigation against any entity (including a
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
85
|
+
or contributory patent infringement, then any patent licenses
|
86
|
+
granted to You under this License for that Work shall terminate
|
87
|
+
as of the date such litigation is filed.
|
88
|
+
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
91
|
+
modifications, and in Source or Object form, provided that You
|
92
|
+
meet the following conditions:
|
93
|
+
|
94
|
+
(a) You must give any other recipients of the Work or
|
95
|
+
Derivative Works a copy of this License; and
|
96
|
+
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
98
|
+
stating that You changed the files; and
|
99
|
+
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
102
|
+
attribution notices from the Source form of the Work,
|
103
|
+
excluding those notices that do not pertain to any part of
|
104
|
+
the Derivative Works; and
|
105
|
+
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
108
|
+
include a readable copy of the attribution notices contained
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
111
|
+
of the following places: within a NOTICE text file distributed
|
112
|
+
as part of the Derivative Works; within the Source form or
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
114
|
+
within a display generated by the Derivative Works, if and
|
115
|
+
wherever such third-party notices normally appear. The contents
|
116
|
+
of the NOTICE file are for informational purposes only and
|
117
|
+
do not modify the License. You may add Your own attribution
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
120
|
+
that such additional attribution notices cannot be construed
|
121
|
+
as modifying the License.
|
122
|
+
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
124
|
+
may provide additional or different license terms and conditions
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
128
|
+
the conditions stated in this License.
|
129
|
+
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
133
|
+
this License, without any additional terms or conditions.
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
135
|
+
the terms of any separate license agreement you may have executed
|
136
|
+
with Licensor regarding such Contributions.
|
137
|
+
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
140
|
+
except as required for reasonable and customary use in describing the
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
142
|
+
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
152
|
+
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
158
|
+
incidental, or consequential damages of any character arising as a
|
159
|
+
result of this License or out of the use or inability to use the
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
162
|
+
other commercial damages or losses), even if such Contributor
|
163
|
+
has been advised of the possibility of such damages.
|
164
|
+
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
168
|
+
or other liability obligations and/or rights consistent with this
|
169
|
+
License. However, in accepting such obligations, You may act only
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
174
|
+
of your accepting any such warranty or additional liability.
|
175
|
+
|
176
|
+
END OF TERMS AND CONDITIONS
|
177
|
+
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
179
|
+
|
180
|
+
To apply the Apache License to your work, attach the following
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
182
|
+
replaced with your own identifying information. (Don't include
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
184
|
+
comment syntax for the file format. We also recommend that a
|
185
|
+
file or class name and description of purpose be included on the
|
186
|
+
same "printed page" as the copyright notice for easier
|
187
|
+
identification within third-party archives.
|
188
|
+
|
189
|
+
Copyright 2019 SignalFx
|
190
|
+
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
192
|
+
you may not use this file except in compliance with the License.
|
193
|
+
You may obtain a copy of the License at
|
194
|
+
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
196
|
+
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
200
|
+
See the License for the specific language governing permissions and
|
201
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
# SignalFx::Lambda
|
2
|
+
|
3
|
+
This gem provides a simplified way to trace AWS Lambda functions written for the
|
4
|
+
Ruby 2.5 runtime.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'signalfx-lambda'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle install --path vendor/bundle
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
Add this line to the top of your file:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
require 'signalfx/lambda'
|
24
|
+
```
|
25
|
+
|
26
|
+
To use the wrapper, register `source.SignalFx::Lambda::Tracing.wrapped_handler`
|
27
|
+
in the console, where `source` is your Ruby source file. Then somewhere after
|
28
|
+
your handler function definition, the function can be registered to be
|
29
|
+
automatically traced:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
# this is the original handler
|
33
|
+
def handler(event:, context:)
|
34
|
+
JSON.generate(body)
|
35
|
+
end
|
36
|
+
|
37
|
+
SignalFx::Lambda::Tracing.register_handler(&method(:handler))
|
38
|
+
```
|
39
|
+
|
40
|
+
`register_handler` will accept any block.
|
41
|
+
|
42
|
+
### Tracer configuration
|
43
|
+
|
44
|
+
The tracer used by the function is configured through environment variables:
|
45
|
+
|
46
|
+
```
|
47
|
+
SIGNALFX_ACCESS_TOKEN
|
48
|
+
SIGNALFX_INGEST_URL
|
49
|
+
SIGNALFX_SERVICE_NAME
|
50
|
+
```
|
51
|
+
|
52
|
+
In production, `SIGNALFX_INGEST_URL` should be pointing to your [Smart Gateway](https://docs.signalfx.com/en/latest/apm/apm-deployment/smart-gateway.html).
|
53
|
+
When pointing to the Smart Gateway, an access token is not needed. When not
|
54
|
+
configured, the ingest URL defaults to `https://ingest.signalfx.com/v1/trace`,
|
55
|
+
which requires an access token to be configured.
|
56
|
+
|
57
|
+
The tracer will be persisted across invocations to the same context, reducing
|
58
|
+
the time needed for tracer initialization.
|
59
|
+
|
60
|
+
## Trace and tags
|
61
|
+
|
62
|
+
The wrapper will generate a single span per function invocation. This span will
|
63
|
+
be named with the pattern `lambda_ruby_<function_name>`. The span prefix can be
|
64
|
+
optionally configured with the `SIGNALFX_SPAN_PREFIX` environment variable:
|
65
|
+
|
66
|
+
$ SIGNALFX_SPAN_PREFIX=custom_prefix_
|
67
|
+
|
68
|
+
This will make spans have the name `custom_prefix_<function_name>`
|
69
|
+
|
70
|
+
Each span will also have the following tags:
|
71
|
+
- `component`: `ruby-lambda-wrapper`
|
72
|
+
- `lambda_arn`: the full ARN of the invocation
|
73
|
+
- `aws_request_id`: the identifier of the invocation request
|
74
|
+
- `aws_region`: the region that the function executed in
|
75
|
+
- `aws_account_id`: id of the account this function ran for
|
76
|
+
- `aws_function_name`: the function name set for this Lambda
|
77
|
+
- `aws_function_version`: the function version
|
78
|
+
- `aws_execution_env`: the name of the runtime environment running this function
|
79
|
+
- `log_group_name`: log group for the function
|
80
|
+
- `log_stream_name`: log stream for the instance
|
81
|
+
- `function_wrapper_version`: the version of this wrapper gem being used
|
82
|
+
|
83
|
+
If a `qualifier` is present in the ARN, depending on the resource type, either `aws_function_qualifier` or `event_source_mappings` will be tagged.
|
84
|
+
|
85
|
+
## Manual Tracing
|
86
|
+
|
87
|
+
Manual tracing may be useful to get a better view into the function. The
|
88
|
+
OpenTracing global tracer makes the tracer used by the wrapper available
|
89
|
+
to when more specific instrumentation is desired.
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
require 'opentracing'
|
93
|
+
|
94
|
+
OpenTracing.global_tracer.start_active_span("span_name") do |scope|
|
95
|
+
|
96
|
+
work_to_be_traced
|
97
|
+
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
These manually created spans will automatically be nested, with the span for the
|
102
|
+
Lambda handler as the parent.
|
103
|
+
|
104
|
+
For more examples of usage, please see [opentracing-ruby](https://github.com/opentracing/opentracing-ruby).
|
105
|
+
|
106
|
+
## Development
|
107
|
+
|
108
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
109
|
+
|
110
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
111
|
+
|
112
|
+
## Contributing
|
113
|
+
|
114
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/signalfx/lambda-ruby.
|
115
|
+
|
116
|
+
## License
|
117
|
+
|
118
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "lambda/tracing"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This is only needed until the next release of the jaeger client
|
4
|
+
module SignalFx
|
5
|
+
module Lambda
|
6
|
+
module Tracing
|
7
|
+
class B3RackCodec
|
8
|
+
class Keys
|
9
|
+
TRACE_ID = 'HTTP_X_B3_TRACEID'.freeze
|
10
|
+
SPAN_ID = 'HTTP_X_B3_SPANID'.freeze
|
11
|
+
PARENT_SPAN_ID = 'HTTP_X_B3_PARENTSPANID'.freeze
|
12
|
+
FLAGS = 'HTTP_X_B3_FLAGS'.freeze
|
13
|
+
SAMPLED = 'HTTP_X_B3_SAMPLED'.freeze
|
14
|
+
end.freeze
|
15
|
+
|
16
|
+
def self.extract(carrier)
|
17
|
+
B3CodecCommon.extract(carrier, Keys)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class B3TextMapCodec
|
22
|
+
class Keys
|
23
|
+
TRACE_ID = 'x-b3-traceid'.freeze
|
24
|
+
SPAN_ID = 'x-b3-spanid'.freeze
|
25
|
+
PARENT_SPAN_ID = 'x-b3-parentspanid'.freeze
|
26
|
+
FLAGS = 'x-b3-flags'.freeze
|
27
|
+
SAMPLED = 'x-b3-sampled'.freeze
|
28
|
+
end.freeze
|
29
|
+
|
30
|
+
def self.extract(carrier)
|
31
|
+
B3CodecCommon.extract(carrier, Keys)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class B3CodecCommon
|
36
|
+
def self.extract(carrier, keys)
|
37
|
+
trace_id = TraceId.base16_hex_id_to_uint64(carrier[keys::TRACE_ID])
|
38
|
+
span_id = TraceId.base16_hex_id_to_uint64(carrier[keys::SPAN_ID])
|
39
|
+
parent_id = TraceId.base16_hex_id_to_uint64(carrier[keys::PARENT_SPAN_ID])
|
40
|
+
flags = parse_flags(carrier[keys::FLAGS], carrier[keys::SAMPLED])
|
41
|
+
|
42
|
+
return nil if span_id.nil? || trace_id.nil?
|
43
|
+
return nil if span_id.zero? || trace_id.zero?
|
44
|
+
|
45
|
+
SpanContext.new(
|
46
|
+
trace_id: trace_id,
|
47
|
+
parent_id: parent_id,
|
48
|
+
span_id: span_id,
|
49
|
+
flags: flags
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
# if the flags header is '1' then the sampled header should not be present
|
54
|
+
def self.parse_flags(flags_header, sampled_header)
|
55
|
+
if flags_header == '1'
|
56
|
+
Jaeger::SpanContext::Flags::DEBUG
|
57
|
+
else
|
58
|
+
TraceId.base16_hex_id_to_uint64(sampled_header)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
private_class_method :parse_flags
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'signalfx/lambda/tracing/extractors'
|
2
|
+
|
3
|
+
require 'opentracing'
|
4
|
+
require 'jaeger/client'
|
5
|
+
|
6
|
+
module SignalFx
|
7
|
+
module Lambda
|
8
|
+
module Tracing
|
9
|
+
class Error < StandardError; end
|
10
|
+
|
11
|
+
def self.wrap_function(event, context, &block)
|
12
|
+
init_tracer(event) if !@tracer # avoid initializing except on a cold start
|
13
|
+
|
14
|
+
scope = OpenTracing.start_active_span("#{@span_prefix}#{context.function_name}", tags: build_tags(context))
|
15
|
+
|
16
|
+
response = yield event: event, context: context
|
17
|
+
scope.span.set_tag("http.status_code", response[:statusCode]) if response[:statusCode]
|
18
|
+
|
19
|
+
response
|
20
|
+
rescue => error
|
21
|
+
if scope
|
22
|
+
scope.span.set_tag("error", true)
|
23
|
+
scope.span.log_kv(key: "message", value: error.message)
|
24
|
+
end
|
25
|
+
|
26
|
+
# pass this error up
|
27
|
+
raise
|
28
|
+
ensure
|
29
|
+
scope.close if scope
|
30
|
+
|
31
|
+
# flush the spans before leaving the execution context
|
32
|
+
@reporter.flush
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.wrapped_handler(event:, context:)
|
36
|
+
wrap_function(event, context, &@handler)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.build_tags(context)
|
40
|
+
tags = {
|
41
|
+
'component' => 'ruby-lambda-wrapper',
|
42
|
+
'lambda_arn' => context.invoked_function_arn,
|
43
|
+
'aws_request_id' => context.aws_request_id,
|
44
|
+
'aws_function_name' => context.function_name,
|
45
|
+
'aws_function_version' => context.function_version,
|
46
|
+
'aws_execution_env' => ENV['AWS_EXECUTION_ENV'],
|
47
|
+
'log_group_name' => context.log_group_name,
|
48
|
+
'log_stream_name' => context.log_stream_name,
|
49
|
+
'function_wrapper_version' => "signalfx-lambda-#{SignalFx::Lambda::VERSION}",
|
50
|
+
}
|
51
|
+
|
52
|
+
tags = tags.merge(tags_from_arn(context.invoked_function_arn))
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.tags_from_arn(arn)
|
56
|
+
_, _, _, region, account_id, resource_type, _, qualifier = arn.split(':')
|
57
|
+
|
58
|
+
tags = {
|
59
|
+
'aws_region' => region,
|
60
|
+
'aws_account_id' => account_id,
|
61
|
+
}
|
62
|
+
|
63
|
+
if qualifier
|
64
|
+
case resource_type
|
65
|
+
when 'function'
|
66
|
+
tags['aws_function_qualifier'] = qualifier
|
67
|
+
when 'event-source-mappings'
|
68
|
+
tags['event_source_mappings'] = qualifier
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
tags
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.register_handler(&handler)
|
76
|
+
@handler = handler
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.init_tracer(event)
|
80
|
+
access_token = ENV['SIGNALFX_ACCESS_TOKEN']
|
81
|
+
ingest_url = ENV['SIGNALFX_INGEST_URL'] || 'https://ingest.signalfx.com/v1/trace'
|
82
|
+
service_name = ENV['SIGNALFX_SERVICE_NAME'] || event.function_name
|
83
|
+
@span_prefix = ENV['SIGNALFX_SPAN_PREFIX'] || 'lambda_ruby_'
|
84
|
+
|
85
|
+
# configure the trace reporter
|
86
|
+
headers = { }
|
87
|
+
headers['X-SF-Token'] = access_token if !access_token.empty?
|
88
|
+
encoder = Jaeger::Client::Encoders::ThriftEncoder.new(service_name: service_name)
|
89
|
+
sender = Jaeger::Client::HttpSender.new(url: ingest_url, headers: headers, encoder: encoder, logger: Logger.new(STDOUT))
|
90
|
+
@reporter = Jaeger::Client::Reporters::RemoteReporter.new(sender: sender, flush_interval: 1)
|
91
|
+
|
92
|
+
# propagation format configuration
|
93
|
+
injectors = {
|
94
|
+
OpenTracing::FORMAT_TEXT_MAP => [Jaeger::Client::Injectors::B3RackCodec]
|
95
|
+
}
|
96
|
+
extractors = {
|
97
|
+
OpenTracing::FORMAT_TEXT_MAP => [SignalFx::Lambda::Tracing::B3TextMapCodec]
|
98
|
+
}
|
99
|
+
|
100
|
+
OpenTracing.global_tracer = Jaeger::Client.build(
|
101
|
+
service_name: service_name,
|
102
|
+
reporter: @reporter,
|
103
|
+
injectors: injectors,
|
104
|
+
extractors: extractors
|
105
|
+
)
|
106
|
+
|
107
|
+
@tracer = OpenTracing.global_tracer
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "signalfx/lambda/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "signalfx-lambda"
|
8
|
+
spec.version = SignalFx::Lambda::VERSION
|
9
|
+
spec.authors = ["Ashwin Chandrasekar"]
|
10
|
+
spec.email = ["achandrasekar@signalfx.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Lambda handler wrapper}
|
13
|
+
spec.homepage = "https://github.com/signalfx/lambda-ruby"
|
14
|
+
spec.license = "Apache-2.0"
|
15
|
+
|
16
|
+
# Specify which files should be added to the gem when it is released.
|
17
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
18
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
19
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
+
end
|
21
|
+
spec.bindir = "exe"
|
22
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
+
spec.require_paths = ["lib"]
|
24
|
+
|
25
|
+
spec.add_dependency "jaeger-client", "~> 0.10.0"
|
26
|
+
spec.add_dependency "opentracing", "~> 0.3"
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: signalfx-lambda
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ashwin Chandrasekar
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-01-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: jaeger-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.10.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.10.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: opentracing
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.17'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.17'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- achandrasekar@signalfx.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- bin/console
|
82
|
+
- bin/setup
|
83
|
+
- lib/signalfx/lambda.rb
|
84
|
+
- lib/signalfx/lambda/tracing.rb
|
85
|
+
- lib/signalfx/lambda/tracing/extractors.rb
|
86
|
+
- lib/signalfx/lambda/version.rb
|
87
|
+
- signalfx-lambda.gemspec
|
88
|
+
homepage: https://github.com/signalfx/lambda-ruby
|
89
|
+
licenses:
|
90
|
+
- Apache-2.0
|
91
|
+
metadata: {}
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
requirements: []
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 2.7.3
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: Lambda handler wrapper
|
112
|
+
test_files: []
|