Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stack trace collection support #4269

Draft
wants to merge 2 commits into
base: vpellan/meta-struct
Choose a base branch
from

Conversation

vpellan
Copy link
Contributor

@vpellan vpellan commented Jan 9, 2025

What does this PR do?

This PR adds stack trace collection support using meta_struct

Motivation:

Stack trace collection is required for exploit prevention.

Change log entry

None.

Additional Notes:

How to test the change?

@github-actions github-actions bot added integrations Involves tracing integrations appsec Application Security monitoring product tracing labels Jan 9, 2025
@datadog-datadog-prod-us1
Copy link
Contributor

datadog-datadog-prod-us1 bot commented Jan 9, 2025

Datadog Report

Branch report: vpellan/stack-trace-collection
Commit report: a6ab36f
Test service: dd-trace-rb

❌ 9 Failed (0 Known Flaky), 21946 Passed, 1476 Skipped, 5m 27.74s Total Time

❌ Failed Tests (9)

This report shows up to 5 failed tests.

  • Datadog::AppSec::ActionsHandler.handle calls both generate_stack and block_request when both are present - rspec - Details

    Expand for error
     undefined method \`trace' for nil:NilClass
     Did you mean?  trap
     
     Failure/Error: service_entry_operation = context.trace || context.span
     
     NoMethodError:
       undefined method \`trace' for nil:NilClass
       Did you mean?  trap
     ./lib/datadog/appsec/stack_trace.rb:82:in \`add_stack_trace'
     ./lib/datadog/appsec/actions_handler.rb:23:in \`generate_stack'
     ...
    
  • Datadog::AppSec::ActionsHandler.handle calls both generate_stack and generate_schema when both are present - rspec - Details

    Expand for error
     undefined method \`trace' for nil:NilClass
     Did you mean?  trap
     
     Failure/Error: service_entry_operation = context.trace || context.span
     
     NoMethodError:
       undefined method \`trace' for nil:NilClass
       Did you mean?  trap
     ./lib/datadog/appsec/stack_trace.rb:82:in \`add_stack_trace'
     ./lib/datadog/appsec/actions_handler.rb:23:in \`generate_stack'
     ...
    
  • Datadog::AppSec::ActionsHandler.handle calls both generate_stack and redirect_request when both are present - rspec - Details

    Expand for error
     undefined method \`trace' for nil:NilClass
     Did you mean?  trap
     
     Failure/Error: service_entry_operation = context.trace || context.span
     
     NoMethodError:
       undefined method \`trace' for nil:NilClass
       Did you mean?  trap
     ./lib/datadog/appsec/stack_trace.rb:82:in \`add_stack_trace'
     ./lib/datadog/appsec/actions_handler.rb:23:in \`generate_stack'
     ...
    
  • Datadog::AppSec::ActionsHandler.handle calls generate_stack with action parameters - rspec - Details

    Expand for error
     undefined method \`trace' for nil:NilClass
     Did you mean?  trap
     
     Failure/Error: service_entry_operation = context.trace || context.span
     
     NoMethodError:
       undefined method \`trace' for nil:NilClass
       Did you mean?  trap
     ./lib/datadog/appsec/stack_trace.rb:82:in \`add_stack_trace'
     ./lib/datadog/appsec/actions_handler.rb:23:in \`generate_stack'
     ...
    
  • Datadog::Tracing::Span#to_hash is expected to eq {:error=>0, :meta=>{}, :metrics=>{}, :name=>"my.span", :parent_id=>0, :resource=>"my.span", :service=>nil, :span_id=>34, :span_links=>[], :trace_id=>12, :type=>nil} - rspec - Details

    Expand for error
     expected: {:error=>0, :meta=>{}, :metrics=>{}, :name=>"my.span", :parent_id=>0, :resource=>"my.span", :service=>nil, :span_id=>34, :span_links=>[], :trace_id=>12, :type=>nil}
          got: {:error=>0, :meta=>{}, :meta_struct=>{}, :metrics=>{}, :name=>"my.span", :parent_id=>0, :resource=>"my.span", :service=>nil, :span_id=>34, :span_links=>[], :trace_id=>12, :type=>nil}
     
     (compared using ==)
     
     Diff:
     @@ -1,5 +1,6 @@
      :error => 0,
      :meta => {},
     +:meta_struct => {},
     ...
    

@pr-commenter
Copy link

pr-commenter bot commented Jan 9, 2025

Benchmarks

Benchmark execution time: 2025-01-31 12:34:38

Comparing candidate commit 7aa25ec in PR branch vpellan/stack-trace-collection with baseline commit b9e8d5d in branch vpellan/meta-struct.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 31 metrics, 2 unstable metrics.

@vpellan vpellan force-pushed the vpellan/stack-trace-collection branch from f79044e to 77e9969 Compare January 14, 2025 15:40

it 'creates a stack trace with 4 top frames' do
expect(dd_stack_trace.frames.size).to eq(4)
expect(dd_stack_trace.frames[0].text).to eq(stack_trace[0].to_s)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(dd_stack_trace.frames[0].text).to eq(stack_trace[0].to_s)
expect(dd_stack_trace.frames[0].text).to eq(stack_trace.first.to_s)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation


it 'creates a stack trace with 4 frames, 1 top' do
expect(dd_stack_trace.frames.size).to eq(4)
expect(dd_stack_trace.frames[0].text).to eq(stack_trace[0].to_s)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(dd_stack_trace.frames[0].text).to eq(stack_trace[0].to_s)
expect(dd_stack_trace.frames[0].text).to eq(stack_trace.first.to_s)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation

@vpellan vpellan force-pushed the vpellan/stack-trace-collection branch from 5d75fc3 to 255e242 Compare January 21, 2025 16:17
@@ -35,7 +35,7 @@ def self.subscribe(engine, context)
next unless result.match?

yield result
throw(:block, true) unless result.actions.empty?
throw(:block, true) if result.actions.include?('block')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we changing this everywhere?

@datadog-datadog-prod-us1
Copy link
Contributor

datadog-datadog-prod-us1 bot commented Jan 23, 2025

Datadog Report

Branch report: vpellan/stack-trace-collection
Commit report: 7aa25ec
Test service: dd-trace-rb

❌ 1 Failed (0 Known Flaky), 22009 Passed, 1477 Skipped, 5m 58.18s Total Time

❌ Failed Tests (1)

  • Datadog::Tracing::Metadata when included ::ancestors has all of the tagging behavior in correct order - rspec - Details

    Expand for error
     expected [Datadog::Tracing::Metadata::Analytics, #<Class:0x272432f8>, Datadog::Tracing::Metadata::MetaStruct, Datadog::Tracing::Metadata::StackTrace, Datadog::Tracing::Metadata::Errors] to include Datadog::Tracing::Metadata::Tagging
     Diff:
     @@ -1,4 +1,6 @@
      [Datadog::Tracing::Metadata::Analytics,
     - Datadog::Tracing::Metadata::Tagging,
     + #<Class:0x272432f8>,
     + Datadog::Tracing::Metadata::MetaStruct,
     + Datadog::Tracing::Metadata::StackTrace,
       Datadog::Tracing::Metadata::Errors]
     
     ...
    


it 'creates a stack trace with 4 top frames' do
expect(collection.count).to eq(4)
expect(collection[0].text).to eq(frames[0].to_s)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(collection[0].text).to eq(frames[0].to_s)
expect(collection.first.text).to eq(frames[0].to_s)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation


it 'creates a stack trace with 4 bottom frames' do
expect(collection.count).to eq(4)
expect(collection[0].text).to eq(frames[1].to_s)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(collection[0].text).to eq(frames[1].to_s)
expect(collection.first.text).to eq(frames[1].to_s)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation

@codecov-commenter
Copy link

codecov-commenter commented Jan 24, 2025

Codecov Report

Attention: Patch coverage is 91.75258% with 32 lines in your changes missing coverage. Please review.

Project coverage is 97.69%. Comparing base (4d51a86) to head (a51bde4).
Report is 81 commits behind head on master.

Files with missing lines Patch % Lines
lib/datadog/appsec/actions_handler.rb 30.43% 16 Missing ⚠️
lib/datadog/tracing/metadata/tagging.rb 45.00% 11 Missing ⚠️
lib/datadog/tracing/span_operation.rb 20.00% 4 Missing ⚠️
spec/support/thread_backtrace_helpers.rb 96.42% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4269      +/-   ##
==========================================
- Coverage   97.70%   97.69%   -0.02%     
==========================================
  Files        1359     1366       +7     
  Lines       82479    82864     +385     
  Branches     4198     4222      +24     
==========================================
+ Hits        80589    80955     +366     
- Misses       1890     1909      +19     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.


it 'creates a stack trace with 4 frames, 1 top' do
expect(collection.count).to eq(4)
expect(collection[0].text).to eq(frames[0].to_s)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(collection[0].text).to eq(frames[0].to_s)
expect(collection[0].text).to eq(frames.first.to_s)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation

expect(collection[0].file).to eq(frames[0].path)
expect(collection[0].file.encoding).to eq(Encoding::UTF_8)
expect(collection[0].line).to eq(frames[0].lineno)
expect(collection[0].function).to eq(frames[0].label)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(collection[0].function).to eq(frames[0].label)
expect(collection[0].function).to eq(frames.first.label)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation

expect(collection[0].text).to eq(frames[0].to_s)
expect(collection[0].text.encoding).to eq(Encoding::UTF_8)
expect(collection[0].file).to eq(frames[0].path)
expect(collection[0].file.encoding).to eq(Encoding::UTF_8)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(collection[0].file.encoding).to eq(Encoding::UTF_8)
expect(collection.first.file.encoding).to eq(Encoding::UTF_8)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation


it 'creates a stack trace with 4 top frames' do
expect(collection.count).to eq(4)
expect(collection[0].text).to eq(frames[0].to_s)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(collection[0].text).to eq(frames[0].to_s)
expect(collection[0].text).to eq(frames.first.to_s)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation

expect(collection.count).to eq(1)
expect(collection[0].id).to eq(0)
expect(collection[0].text).to eq(frames[0].to_s)
expect(collection[0].text.encoding).to eq(Encoding::UTF_8)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(collection[0].text.encoding).to eq(Encoding::UTF_8)
expect(collection.first.text.encoding).to eq(Encoding::UTF_8)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation

expect(collection[0].file.encoding).to eq(Encoding::UTF_8)
expect(collection[0].line).to eq(frames[0].lineno)
expect(collection[0].function).to eq(frames[0].label)
expect(collection[0].function.encoding).to eq(Encoding::UTF_8)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(collection[0].function.encoding).to eq(Encoding::UTF_8)
expect(collection.first.function.encoding).to eq(Encoding::UTF_8)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation

expect(collection[0].id).to eq(0)
expect(collection[0].text).to eq(frames[0].to_s)
expect(collection[0].text.encoding).to eq(Encoding::UTF_8)
expect(collection[0].file).to eq(frames[0].path)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(collection[0].file).to eq(frames[0].path)
expect(collection[0].file).to eq(frames.first.path)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation


it 'creates a stack trace with correctly encoded values' do
expect(collection.count).to eq(1)
expect(collection[0].id).to eq(0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(collection[0].id).to eq(0)
expect(collection.first.id).to eq(0)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation


it 'creates a stack trace with 4 bottom frames' do
expect(collection.count).to eq(4)
expect(collection[0].text).to eq(frames[1].to_s)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(collection[0].text).to eq(frames[1].to_s)
expect(collection.first.text).to eq(frames[1].to_s)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation

module StackTrace
# Formatted stack frame.
# This class extends a Struct as it's required by Steep to be able to add a method to it.
class Frame < Struct.new(:id, :text, :file, :line, :function, keyword_init: true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

You should not inherit from Struct.new (...read more)

The rule, "You should not inherit from Struct.new", is important because it can lead to unexpected behavior and bugs in your code. Struct.new creates a new Class, and if you inherit from it, you're creating a subclass of a dynamically generated Class. This can lead to confusing code and can make debugging difficult.

Instead of inheriting from Struct.new, you should assign the result of Struct.new to a constant. This will create a new Class with the provided attributes, and you can add methods to it just like any other Class. This approach is clearer and less prone to errors.

To avoid this, use Struct.new to create a new class and assign it to a constant. For example, Foo = Struct.new(:foo, :bar) creates a new Class with two attributes, foo and bar, and assigns it to the constant Foo. This is a far safer and more predictable way to use Struct.new in your code.

View in Datadog  Leave us feedback  Documentation

module Tracing
module StackTrace
# Represent a stack trace with its id and message in message pack
class Representor < Struct.new(:id, :message, :frames, keyword_init: true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

You should not inherit from Struct.new (...read more)

The rule, "You should not inherit from Struct.new", is important because it can lead to unexpected behavior and bugs in your code. Struct.new creates a new Class, and if you inherit from it, you're creating a subclass of a dynamically generated Class. This can lead to confusing code and can make debugging difficult.

Instead of inheriting from Struct.new, you should assign the result of Struct.new to a constant. This will create a new Class with the provided attributes, and you can add methods to it just like any other Class. This approach is clearer and less prone to errors.

To avoid this, use Struct.new to create a new class and assign it to a constant. For example, Foo = Struct.new(:foo, :bar) creates a new Class with two attributes, foo and bar, and assigns it to the constant Foo. This is a far safer and more predictable way to use Struct.new in your code.

View in Datadog  Leave us feedback  Documentation


it 'creates a stack trace with 4 frames, 1 top' do
expect(collection.count).to eq(4)
expect(collection[0].text).to eq(frames[0].to_s)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(collection[0].text).to eq(frames[0].to_s)
expect(collection[0].text).to eq(frames.first.to_s)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation


stack_trace_group = meta_struct[Metadata::Ext::MetaStruct::TAG_STACK_TRACE][group]
max_collect = Datadog.configuration.appsec.stack_trace.max_collect
return if max_collect > 0 && stack_trace_group.size >= max_collect
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Consider using ranges or between to simplify your comparison (...read more)

The rule "Prefer ranges/between over complex comparisons" advises developers to use the range or between? method for comparisons instead of complex conditional statements. This practice increases the readability and clarity of your code. Complex comparisons using logical operators can be difficult to understand and prone to errors.

This rule is important because it promotes cleaner, more efficient, and easier-to-read code. When code is easier to read, it's easier to maintain, debug, and less likely to contain hidden bugs. Using the range or between? method is a more concise way to check if a value falls within a specific range.

To adhere to this rule, replace complex comparison statements with the range or between? method. For example, instead of writing foo >= 42 && foo <= 99, you can write (42..99).include?(foo) or foo.between?(42, 99). These alternatives are more straightforward and visually cleaner, making your code easier to understand.

View in Datadog  Leave us feedback  Documentation

it 'creates a stack trace with correctly encoded values' do
expect(collection.count).to eq(1)
expect(collection[0].id).to eq(0)
expect(collection[0].text).to eq(frames[0].to_s)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Quality Violation

Suggested change
expect(collection[0].text).to eq(frames[0].to_s)
expect(collection[0].text).to eq(frames.first.to_s)
Improve readability with first (...read more)

This rule encourages the use of first and last methods over array indexing to access the first and last elements of an array, respectively. The primary reason behind this rule is to improve code readability. Using first and last makes it immediately clear that you are accessing the first or last element of the array, which might not be immediately obvious with array indexing, especially for developers who are new to Ruby.

The use of these methods also helps to make your code more idiomatic, which is a crucial aspect of writing effective Ruby code. Idiomatic code is easier to read, understand, and maintain. It also tends to be more efficient, as idioms often reflect patterns that are optimized for the language.

To adhere to this rule, replace the use of array indexing with first or last methods when you want to access the first and last elements of an array. For instance, instead of arr[0] use arr.first and instead of arr[-1] use arr.last. However, note that this rule should be applied only when reading values. When modifying the first or last elements, array indexing should still be used. For example, arr[0] = 'new_value' and arr[-1] = 'new_value'.

View in Datadog  Leave us feedback  Documentation

@vpellan vpellan force-pushed the vpellan/stack-trace-collection branch from 5dfecd6 to 7aa25ec Compare January 31, 2025 12:10
@vpellan vpellan changed the base branch from master to vpellan/meta-struct January 31, 2025 12:11
@vpellan vpellan force-pushed the vpellan/meta-struct branch 2 times, most recently from b3dc5c2 to 0836e11 Compare January 31, 2025 12:48
@vpellan vpellan changed the title Add meta_struct and stack trace collection Add stack trace collection support Jan 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
appsec Application Security monitoring product integrations Involves tracing integrations tracing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants