rspec-trace-formatter 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 523ae0ee65d59fbcc8081aefe0da23355846add224b8465d210eea536a93d9a5
4
- data.tar.gz: a94b8c49db8bf4a1cfd0d00ebdab0136120be9d9d7338294a3b9f173dc612503
3
+ metadata.gz: dae27f097510a3dcb600e0cddcb6d15b79af17db85942d8472696ac4347f7f8f
4
+ data.tar.gz: 8d23c7632ce92d3f67d18868841c4ddc415f2775962bce512de91078f12cb4dc
5
5
  SHA512:
6
- metadata.gz: 73903d8f6cc20a9301eb92105ddd0ec80b9152c389ed6c855ae46118a8793a91a356c24200d6f71295e2bec289dc6a0223d158a750b1d8cd6da6fef43f45a9b1
7
- data.tar.gz: 6afed85a1363970c45fa72d0c37412998d59e6d29334f70c18fc98ce7316376fe8a41f06dee84e28d5c6a894dd9a27ce18f45ee5002b842bfb3ca3617ade6801
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
+ }
@@ -12,7 +12,7 @@ jobs:
12
12
  - uses: actions/checkout@v2
13
13
  - uses: ruby/setup-ruby@v1
14
14
  with:
15
- ruby-version: 2.7
15
+ ruby-version: 3.0
16
16
  - name: StandardRB Lint
17
17
  run: |
18
18
  gem install standardrb
data/.gitignore CHANGED
@@ -48,6 +48,7 @@ build-iPhoneSimulator/
48
48
  Gemfile.lock
49
49
  .ruby-version
50
50
  .ruby-gemset
51
+ .tool-versions
51
52
 
52
53
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
53
54
  .rvmrc
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
- rspec-trace-consumer < /tmp/trace-events.jsonl
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
- ## What's Coming Next?
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
- This does not yet support providing a [parent trace ID with an environment variable](https://github.com/open-telemetry/opentelemetry-specification/issues/740).
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
- The fixtures for the snapshot tests for the `Consumer` class are currently system-specific insofar as the exception stack traces are built from real exceptions that include paths from the Ruby installation that generated them.
84
- Right now they come from my setup, so if anyone else regenerates the fixtures these paths will change.
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
 
@@ -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
- RSpec::Trace::Consumer.new($stdin).run
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
@@ -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
- # TODO: Not this
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
- @contexts.push(@contexts.last.set_value(@current_span_key, span))
124
- @tokens.push(OpenTelemetry::Context.attach(@contexts.last))
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
 
@@ -3,7 +3,7 @@
3
3
  require "active_support/time"
4
4
  require "active_support/json"
5
5
  require "rspec/core"
6
- require "rspec/core/formatters/base_text_formatter"
6
+ require "rspec/core/formatters/base_formatter"
7
7
 
8
8
  require_relative "version"
9
9
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module Trace
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
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.1.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-07 00:00:00.000000000 Z
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"