rspec-trace-formatter 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 +4 -4
- data/.devcontainer/Dockerfile +17 -0
- data/.devcontainer/base.Dockerfile +43 -0
- data/.devcontainer/devcontainer.json +34 -0
- data/.github/workflows/ci.yml +1 -1
- data/.gitignore +1 -0
- data/README.md +31 -9
- data/exe/rspec-trace-consumer +18 -1
- data/lib/rspec/trace/consumer.rb +13 -9
- data/lib/rspec/trace/formatter.rb +1 -1
- data/lib/rspec/trace/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dae27f097510a3dcb600e0cddcb6d15b79af17db85942d8472696ac4347f7f8f
|
4
|
+
data.tar.gz: 8d23c7632ce92d3f67d18868841c4ddc415f2775962bce512de91078f12cb4dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35edff294bbfb5221b476a208f7848dd43d2082f3e262a41bf48fab2206f7bf6489d133ef0836d5813f04a0d36bd7291e79c65fc3db82f860f9773a42476a50a
|
7
|
+
data.tar.gz: 6b3c9b25ce54d2db82f255d2c1e23b1c7abe789c0e5c4ddc1eb7e6f1b21b473eb904fdbcea49add06e24054c1df44da1fb5b9f842db9c0b2711e261d7b1ca53b
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# [Choice] Ruby version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.0, 2, 2.7, 2.6, 3-bullseye, 3.0-bullseye, 2-bullseye, 2.7-bullseye, 2.6-bullseye, 3-buster, 3.0-buster, 2-buster, 2.7-buster, 2.6-buster
|
2
|
+
ARG VARIANT=2-bullseye
|
3
|
+
FROM mcr.microsoft.com/vscode/devcontainers/ruby:0-${VARIANT}
|
4
|
+
|
5
|
+
# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
|
6
|
+
ARG NODE_VERSION="none"
|
7
|
+
RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
|
8
|
+
|
9
|
+
# [Optional] Uncomment this section to install additional OS packages.
|
10
|
+
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
11
|
+
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
12
|
+
|
13
|
+
# [Optional] Uncomment this line to install additional gems.
|
14
|
+
# RUN gem install <your-gem-names-here>
|
15
|
+
|
16
|
+
# [Optional] Uncomment this line to install global node packages.
|
17
|
+
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# [Choice] Ruby version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.0, 2, 2.7, 2.6, 3-bullseye, 3.0-bullseye, 2-bullseye, 2.7-bullseye, 2.6-bullseye, 3-buster, 3.0-buster, 2-buster, 2.7-buster, 2.6-buster
|
2
|
+
ARG VARIANT=2-bullseye
|
3
|
+
FROM ruby:${VARIANT}
|
4
|
+
|
5
|
+
# Copy library scripts to execute
|
6
|
+
COPY library-scripts/*.sh library-scripts/*.env /tmp/library-scripts/
|
7
|
+
|
8
|
+
# [Option] Install zsh
|
9
|
+
ARG INSTALL_ZSH="true"
|
10
|
+
# [Option] Upgrade OS packages to their latest versions
|
11
|
+
ARG UPGRADE_PACKAGES="true"
|
12
|
+
# Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies.
|
13
|
+
ARG USERNAME=vscode
|
14
|
+
ARG USER_UID=1000
|
15
|
+
ARG USER_GID=$USER_UID
|
16
|
+
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
17
|
+
# Remove imagemagick due to https://security-tracker.debian.org/tracker/CVE-2019-10131
|
18
|
+
&& apt-get purge -y imagemagick imagemagick-6-common \
|
19
|
+
# Install common packages, non-root user, rvm, core build tools
|
20
|
+
&& bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" "true" "true" \
|
21
|
+
&& bash /tmp/library-scripts/ruby-debian.sh "none" "${USERNAME}" "true" "true" \
|
22
|
+
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
|
23
|
+
|
24
|
+
# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
|
25
|
+
ARG NODE_VERSION="none"
|
26
|
+
ENV NVM_DIR=/usr/local/share/nvm
|
27
|
+
ENV NVM_SYMLINK_CURRENT=true \
|
28
|
+
PATH=${NVM_DIR}/current/bin:${PATH}
|
29
|
+
RUN bash /tmp/library-scripts/node-debian.sh "${NVM_DIR}" "${NODE_VERSION}" "${USERNAME}" \
|
30
|
+
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*
|
31
|
+
|
32
|
+
# Remove library scripts for final image
|
33
|
+
RUN rm -rf /tmp/library-scripts
|
34
|
+
|
35
|
+
# [Optional] Uncomment this section to install additional OS packages.
|
36
|
+
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
37
|
+
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
38
|
+
|
39
|
+
# [Optional] Uncomment this line to install additional gems.
|
40
|
+
# RUN gem install <your-gem-names-here>
|
41
|
+
|
42
|
+
# [Optional] Uncomment this line to install global node packages.
|
43
|
+
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
|
@@ -0,0 +1,34 @@
|
|
1
|
+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
2
|
+
// https://github.com/microsoft/vscode-dev-containers/tree/v0.205.2/containers/ruby
|
3
|
+
{
|
4
|
+
"name": "Ruby",
|
5
|
+
"build": {
|
6
|
+
"dockerfile": "Dockerfile",
|
7
|
+
"args": {
|
8
|
+
// Update 'VARIANT' to pick a Ruby version: 3, 3.0, 2, 2.7, 2.6
|
9
|
+
// Append -bullseye or -buster to pin to an OS version.
|
10
|
+
// Use -bullseye variants on local on arm64/Apple Silicon.
|
11
|
+
"VARIANT": "3-bullseye",
|
12
|
+
// Options
|
13
|
+
"NODE_VERSION": "none"
|
14
|
+
}
|
15
|
+
},
|
16
|
+
|
17
|
+
// Set *default* container specific settings.json values on container create.
|
18
|
+
"settings": {},
|
19
|
+
|
20
|
+
// Add the IDs of extensions you want installed when the container is created.
|
21
|
+
"extensions": [
|
22
|
+
"rebornix.Ruby"
|
23
|
+
],
|
24
|
+
|
25
|
+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
26
|
+
// "forwardPorts": [],
|
27
|
+
|
28
|
+
// Use 'postCreateCommand' to run commands after the container is created.
|
29
|
+
// "postCreateCommand": "ruby --version",
|
30
|
+
|
31
|
+
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
32
|
+
"remoteUser": "vscode"
|
33
|
+
|
34
|
+
}
|
data/.github/workflows/ci.yml
CHANGED
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -52,22 +52,40 @@ However, the rest of this library is _expected_ to work for you, and [specifying
|
|
52
52
|
|
53
53
|
## How Do I Use It?
|
54
54
|
|
55
|
+
You can install this gem by adding the `rspec-trace-formatter` (along with the necessary OpenTelemetry dependencies, if they aren't already included) to your `Gemfile` and running `bundle install`.
|
56
|
+
For example:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
group :test do
|
60
|
+
gem "rspec-trace-formatter"
|
61
|
+
gem "opentelemetry-api", "~> 1.0"
|
62
|
+
gem "opentelemetry-exporter-otlp", "~> 0.20.0"
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
55
66
|
This library should be used like [any other RSpec formatter](https://relishapp.com/rspec/rspec-core/v/3-10/docs/command-line/format-option), with the assistance of any environment variables that you need to control the OpenTelemetry data.
|
56
67
|
|
57
68
|
Example of using the `RSpec::Trace::OpenTelemetryFormatter` with representative environment variables set:
|
58
69
|
|
59
70
|
```bash
|
60
|
-
OTEL_TRACES_EXPORTER=console bundle exec rspec --format RSpec::Trace::OpenTelemetryFormatter
|
71
|
+
$ OTEL_TRACES_EXPORTER=console bundle exec rspec --format RSpec::Trace::OpenTelemetryFormatter
|
61
72
|
```
|
62
73
|
|
63
74
|
Example of running the `RSpec::Trace::Formatter` by itself and sending the output to `rspec-trace-consumer` separately (in a way that you can surely improve upon):
|
64
75
|
|
65
76
|
```bash
|
66
|
-
OTEL_TRACES_EXPORTER=console bundle exec rspec --format RSpec::Trace::Formatter --out /tmp/trace-events.jsonl
|
77
|
+
$ OTEL_TRACES_EXPORTER=console bundle exec rspec --format RSpec::Trace::Formatter --out /tmp/trace-events.jsonl
|
78
|
+
|
79
|
+
# Piping the input in
|
80
|
+
$ rspec-trace-consumer < /tmp/trace-events.jsonl
|
67
81
|
|
68
|
-
|
82
|
+
# Passing a filename as an argument
|
83
|
+
$ rspec-trace-consumer /tmp/trace-events.jsonl
|
69
84
|
```
|
70
85
|
|
86
|
+
If the `TRACEPARENT` environment variable is set in either of these cases, it will be interpreted as a [W3C Trace Context Traceparent Header value](https://www.w3.org/TR/trace-context/#traceparent-header).
|
87
|
+
This will allow you to include the span events generated by this library in a larger distributed trace.
|
88
|
+
|
71
89
|
## How Do I Contribute?
|
72
90
|
|
73
91
|
Very carefully, I hope.
|
@@ -75,14 +93,18 @@ Very carefully, I hope.
|
|
75
93
|
One notable fact is that we use [snapshot testing](https://github.com/levinmr/rspec-snapshot) for the class underpinning `rspec-trace-consumer`.
|
76
94
|
To keep this reliable, I've defined a custom OpenTelemetry span exporter that includes meaningful-enough data to test with and no execution-specific fields.
|
77
95
|
|
78
|
-
|
96
|
+
### Useful `rake` commands
|
97
|
+
|
98
|
+
* `rake build`: Build the gem
|
99
|
+
* `rake install`: Builds and installs the gem
|
100
|
+
* `rake regenerate_examples`: Rebuilds fixtures for snapshot tests
|
101
|
+
* `rake test`: Runs the automated tests (written with RSpec, of course)
|
102
|
+
* `rake update_snapshots`: Updates the test snapshots
|
79
103
|
|
80
|
-
|
81
|
-
I haven't done it yet because it's not very helpful to me given my primary use case, but I'll add that soon enough.
|
104
|
+
### Containers
|
82
105
|
|
83
|
-
|
84
|
-
|
85
|
-
I believe that the ideal way to fix this is to provide a containerized development environment for which these paths can be fixed for everyone.
|
106
|
+
Configuration for a [dev container](https://code.visualstudio.com/docs/remote/containers) is provided for convenience.
|
107
|
+
The main practical benefit of developing in the container is to be able to regenerate the snapshots for the `Consumer` tests with consistent and non-identifying file paths for the stack traces.
|
86
108
|
|
87
109
|
## License
|
88
110
|
|
data/exe/rspec-trace-consumer
CHANGED
@@ -2,6 +2,23 @@
|
|
2
2
|
|
3
3
|
$LOAD_PATH.unshift("#{__dir__}/../lib")
|
4
4
|
|
5
|
+
require "optionparser"
|
5
6
|
require "rspec/trace"
|
6
7
|
|
7
|
-
|
8
|
+
OptionParser.new do |opts|
|
9
|
+
opts.banner = "Usage: rspec-trace-consumer [path]"
|
10
|
+
opts.on("-v", "--version", "Prints the current library version") do
|
11
|
+
puts RSpec::Trace::VERSION
|
12
|
+
exit 0
|
13
|
+
end
|
14
|
+
end.parse!
|
15
|
+
|
16
|
+
input_file = ARGV.pop
|
17
|
+
input = if input_file
|
18
|
+
File.open(input_file, "r")
|
19
|
+
else
|
20
|
+
$stdin
|
21
|
+
end
|
22
|
+
|
23
|
+
OpenTelemetry::SDK.configure
|
24
|
+
RSpec::Trace::Consumer.new(input, ENV["TRACEPARENT"]).run
|
data/lib/rspec/trace/consumer.rb
CHANGED
@@ -7,18 +7,13 @@ require "opentelemetry/exporter/otlp"
|
|
7
7
|
module RSpec
|
8
8
|
module Trace
|
9
9
|
class Consumer
|
10
|
-
def initialize(input)
|
10
|
+
def initialize(input, traceparent_string = nil)
|
11
11
|
@input = input
|
12
|
-
OpenTelemetry::SDK.configure do |c|
|
13
|
-
c.service_name = ENV.fetch("OTEL_SERVICE_NAME", "rspec")
|
14
|
-
end
|
15
12
|
@tracer_provider = OpenTelemetry.tracer_provider
|
16
13
|
@tracer_provider.sampler = OpenTelemetry::SDK::Trace::Samplers::ALWAYS_ON
|
17
14
|
@tracer = @tracer_provider.tracer("rspec-trace-formatter", RSpec::Trace::VERSION)
|
18
15
|
@spans = []
|
19
|
-
|
20
|
-
@current_span_key = OpenTelemetry::Trace.const_get(:CURRENT_SPAN_KEY)
|
21
|
-
@contexts = [OpenTelemetry::Context.empty]
|
16
|
+
@contexts = [load_context_from_traceparent(traceparent_string)]
|
22
17
|
@tokens = []
|
23
18
|
end
|
24
19
|
|
@@ -110,6 +105,14 @@ module RSpec
|
|
110
105
|
|
111
106
|
private
|
112
107
|
|
108
|
+
def load_context_from_traceparent(traceparent_string)
|
109
|
+
return OpenTelemetry::Context.current unless traceparent_string
|
110
|
+
|
111
|
+
OpenTelemetry::Trace::Propagation::TraceContext.text_map_propagator.extract(
|
112
|
+
{"traceparent" => traceparent_string}
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
113
116
|
def parse_event(line)
|
114
117
|
event = JSON.parse(line, symbolize_names: true)
|
115
118
|
event[:timestamp] = Time.parse(event[:timestamp])
|
@@ -120,8 +123,9 @@ module RSpec
|
|
120
123
|
@tracer.start_span(name, start_timestamp: timestamp, with_parent: @contexts.last).tap do |span|
|
121
124
|
yield span if block_given?
|
122
125
|
@spans.push(span)
|
123
|
-
|
124
|
-
@
|
126
|
+
new_context = OpenTelemetry::Trace.context_with_span(span, parent_context: @contexts.last)
|
127
|
+
@contexts.push(new_context)
|
128
|
+
@tokens.push(OpenTelemetry::Context.attach(new_context))
|
125
129
|
end
|
126
130
|
end
|
127
131
|
|
data/lib/rspec/trace/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-trace-formatter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zach Thomae
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: opentelemetry-api
|
@@ -215,6 +215,9 @@ executables:
|
|
215
215
|
extensions: []
|
216
216
|
extra_rdoc_files: []
|
217
217
|
files:
|
218
|
+
- ".devcontainer/Dockerfile"
|
219
|
+
- ".devcontainer/base.Dockerfile"
|
220
|
+
- ".devcontainer/devcontainer.json"
|
218
221
|
- ".github/workflows/ci.yml"
|
219
222
|
- ".gitignore"
|
220
223
|
- ".rspec"
|