sentry-ruby 5.8.0 → 5.12.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.
data/lib/sentry/scope.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "sentry/breadcrumb_buffer"
4
+ require "sentry/propagation_context"
4
5
  require "etc"
5
6
 
6
7
  module Sentry
@@ -20,7 +21,8 @@ module Sentry
20
21
  :event_processors,
21
22
  :rack_env,
22
23
  :span,
23
- :session
24
+ :session,
25
+ :propagation_context
24
26
  ]
25
27
 
26
28
  attr_reader(*ATTRIBUTES)
@@ -50,7 +52,10 @@ module Sentry
50
52
  event.transaction_info = { source: transaction_source } if transaction_source
51
53
 
52
54
  if span
53
- event.contexts[:trace] = span.get_trace_context
55
+ event.contexts[:trace] ||= span.get_trace_context
56
+ else
57
+ event.contexts[:trace] ||= propagation_context.get_trace_context
58
+ event.dynamic_sampling_context ||= propagation_context.get_dynamic_sampling_context
54
59
  end
55
60
 
56
61
  event.fingerprint = fingerprint
@@ -95,6 +100,7 @@ module Sentry
95
100
  copy.fingerprint = fingerprint.deep_dup
96
101
  copy.span = span.deep_dup
97
102
  copy.session = session.deep_dup
103
+ copy.propagation_context = propagation_context.deep_dup
98
104
  copy
99
105
  end
100
106
 
@@ -111,6 +117,7 @@ module Sentry
111
117
  self.transaction_sources = scope.transaction_sources
112
118
  self.fingerprint = scope.fingerprint
113
119
  self.span = scope.span
120
+ self.propagation_context = scope.propagation_context
114
121
  end
115
122
 
116
123
  # Updates the scope's data from the given options.
@@ -192,6 +199,10 @@ module Sentry
192
199
  # @return [Hash]
193
200
  def set_contexts(contexts_hash)
194
201
  check_argument_type!(contexts_hash, Hash)
202
+ contexts_hash.values.each do |val|
203
+ check_argument_type!(val, Hash)
204
+ end
205
+
195
206
  @contexts.merge!(contexts_hash) do |key, old, new|
196
207
  old.merge(new)
197
208
  end
@@ -268,6 +279,13 @@ module Sentry
268
279
  @event_processors << block
269
280
  end
270
281
 
282
+ # Generate a new propagation context either from the incoming env headers or from scratch.
283
+ # @param env [Hash, nil]
284
+ # @return [void]
285
+ def generate_propagation_context(env = nil)
286
+ @propagation_context = PropagationContext.new(self, env)
287
+ end
288
+
271
289
  protected
272
290
 
273
291
  # for duplicating scopes internally
@@ -288,6 +306,7 @@ module Sentry
288
306
  @rack_env = {}
289
307
  @span = nil
290
308
  @session = nil
309
+ generate_propagation_context
291
310
  set_new_breadcrumb_buffer
292
311
  end
293
312
 
@@ -305,7 +324,8 @@ module Sentry
305
324
  name: uname[:sysname] || RbConfig::CONFIG["host_os"],
306
325
  version: uname[:version],
307
326
  build: uname[:release],
308
- kernel_version: uname[:version]
327
+ kernel_version: uname[:version],
328
+ machine: uname[:machine]
309
329
  }
310
330
  end
311
331
  end
data/lib/sentry/span.rb CHANGED
@@ -4,6 +4,43 @@ require "securerandom"
4
4
 
5
5
  module Sentry
6
6
  class Span
7
+
8
+ # We will try to be consistent with OpenTelemetry on this front going forward.
9
+ # https://develop.sentry.dev/sdk/performance/span-data-conventions/
10
+ module DataConventions
11
+ URL = "url"
12
+ HTTP_STATUS_CODE = "http.response.status_code"
13
+ HTTP_QUERY = "http.query"
14
+ HTTP_METHOD = "http.request.method"
15
+
16
+ # An identifier for the database management system (DBMS) product being used.
17
+ # Example: postgresql
18
+ DB_SYSTEM = "db.system"
19
+
20
+ # The name of the database being accessed.
21
+ # For commands that switch the database, this should be set to the target database
22
+ # (even if the command fails).
23
+ # Example: myDatabase
24
+ DB_NAME = "db.name"
25
+
26
+ # Name of the database host.
27
+ # Example: example.com
28
+ SERVER_ADDRESS = "server.address"
29
+
30
+ # Logical server port number
31
+ # Example: 80; 8080; 443
32
+ SERVER_PORT = "server.port"
33
+
34
+ # Physical server IP address or Unix socket address.
35
+ # Example: 10.5.3.2
36
+ SERVER_SOCKET_ADDRESS = "server.socket.address"
37
+
38
+ # Physical server port.
39
+ # Recommended: If different than server.port.
40
+ # Example: 16456
41
+ SERVER_SOCKET_PORT = "server.socket.port"
42
+ end
43
+
7
44
  STATUS_MAP = {
8
45
  400 => "invalid_argument",
9
46
  401 => "unauthenticated",
@@ -75,7 +112,7 @@ module Sentry
75
112
  timestamp: nil
76
113
  )
77
114
  @trace_id = trace_id || SecureRandom.uuid.delete("-")
78
- @span_id = span_id || SecureRandom.hex(8)
115
+ @span_id = span_id || SecureRandom.uuid.delete("-").slice(0, 16)
79
116
  @parent_span_id = parent_span_id
80
117
  @sampled = sampled
81
118
  @start_timestamp = start_timestamp || Sentry.utc_now.to_f
@@ -208,7 +245,7 @@ module Sentry
208
245
  # @param status_code [String] example: "500".
209
246
  def set_http_status(status_code)
210
247
  status_code = status_code.to_i
211
- set_data("status_code", status_code)
248
+ set_data(DataConventions::HTTP_STATUS_CODE, status_code)
212
249
 
213
250
  status =
214
251
  if status_code >= 200 && status_code < 299
@@ -14,24 +14,28 @@ module Sentry
14
14
  # @return [void]
15
15
  def setup_sentry_test(&block)
16
16
  raise "please make sure the SDK is initialized for testing" unless Sentry.initialized?
17
- copied_config = Sentry.configuration.dup
17
+ dummy_config = Sentry.configuration.dup
18
18
  # configure dummy DSN, so the events will not be sent to the actual service
19
- copied_config.dsn = DUMMY_DSN
19
+ dummy_config.dsn = DUMMY_DSN
20
20
  # set transport to DummyTransport, so we can easily intercept the captured events
21
- copied_config.transport.transport_class = Sentry::DummyTransport
21
+ dummy_config.transport.transport_class = Sentry::DummyTransport
22
22
  # make sure SDK allows sending under the current environment
23
- copied_config.enabled_environments << copied_config.environment unless copied_config.enabled_environments.include?(copied_config.environment)
23
+ dummy_config.enabled_environments << dummy_config.environment unless dummy_config.enabled_environments.include?(dummy_config.environment)
24
24
  # disble async event sending
25
- copied_config.background_worker_threads = 0
25
+ dummy_config.background_worker_threads = 0
26
26
 
27
27
  # user can overwrite some of the configs, with a few exceptions like:
28
28
  # - include_local_variables
29
29
  # - auto_session_tracking
30
- block&.call(copied_config)
30
+ block&.call(dummy_config)
31
31
 
32
- test_client = Sentry::Client.new(copied_config)
32
+ # the base layer's client should already use the dummy config so nothing will be sent by accident
33
+ base_client = Sentry::Client.new(dummy_config)
34
+ Sentry.get_current_hub.bind_client(base_client)
35
+ # create a new layer so mutations made to the testing scope or configuration could be simply popped later
36
+ Sentry.get_current_hub.push_scope
37
+ test_client = Sentry::Client.new(dummy_config.dup)
33
38
  Sentry.get_current_hub.bind_client(test_client)
34
- Sentry.get_current_scope.clear
35
39
  end
36
40
 
37
41
  # Clears all stored events and envelopes.
@@ -40,9 +44,12 @@ module Sentry
40
44
  def teardown_sentry_test
41
45
  return unless Sentry.initialized?
42
46
 
43
- sentry_transport.events = []
44
- sentry_transport.envelopes = []
45
- Sentry.get_current_scope.clear
47
+ # pop testing layer created by `setup_sentry_test`
48
+ # but keep the base layer to avoid nil-pointer errors
49
+ # TODO: find a way to notify users if they somehow popped the test layer before calling this method
50
+ if Sentry.get_current_hub.instance_variable_get(:@stack).size > 1
51
+ Sentry.get_current_hub.pop_scope
52
+ end
46
53
  end
47
54
 
48
55
  # @return [Transport]
@@ -75,4 +82,3 @@ module Sentry
75
82
  end
76
83
  end
77
84
  end
78
-
@@ -1,16 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "sentry/baggage"
4
+ require "sentry/profiler"
5
+ require "sentry/propagation_context"
4
6
 
5
7
  module Sentry
6
8
  class Transaction < Span
7
- SENTRY_TRACE_REGEXP = Regexp.new(
8
- "^[ \t]*" + # whitespace
9
- "([0-9a-f]{32})?" + # trace_id
10
- "-?([0-9a-f]{16})?" + # span_id
11
- "-?([01])?" + # sampled
12
- "[ \t]*$" # whitespace
13
- )
9
+ # @deprecated Use Sentry::PropagationContext::SENTRY_TRACE_REGEXP instead.
10
+ SENTRY_TRACE_REGEXP = PropagationContext::SENTRY_TRACE_REGEXP
11
+
14
12
  UNLABELD_NAME = "<unlabeled transaction>".freeze
15
13
  MESSAGE_PREFIX = "[Tracing]"
16
14
 
@@ -58,6 +56,10 @@ module Sentry
58
56
  # @return [Hash]
59
57
  attr_reader :contexts
60
58
 
59
+ # The Profiler instance for this transaction.
60
+ # @return [Profiler]
61
+ attr_reader :profiler
62
+
61
63
  def initialize(
62
64
  hub:,
63
65
  name: nil,
@@ -83,9 +85,12 @@ module Sentry
83
85
  @effective_sample_rate = nil
84
86
  @contexts = {}
85
87
  @measurements = {}
88
+ @profiler = Profiler.new(@configuration)
86
89
  init_span_recorder
87
90
  end
88
91
 
92
+ # @deprecated use Sentry.continue_trace instead.
93
+ #
89
94
  # Initalizes a Transaction instance with a Sentry trace string from another transaction (usually from an external request).
90
95
  #
91
96
  # The original transaction will become the parent of the new Transaction instance. And they will share the same `trace_id`.
@@ -126,18 +131,10 @@ module Sentry
126
131
  )
127
132
  end
128
133
 
129
- # Extract the trace_id, parent_span_id and parent_sampled values from a sentry-trace header.
130
- #
131
- # @param sentry_trace [String] the sentry-trace header value from the previous transaction.
134
+ # @deprecated Use Sentry::PropagationContext.extract_sentry_trace instead.
132
135
  # @return [Array, nil]
133
136
  def self.extract_sentry_trace(sentry_trace)
134
- match = SENTRY_TRACE_REGEXP.match(sentry_trace)
135
- return nil if match.nil?
136
-
137
- trace_id, parent_span_id, sampled_flag = match[1..3]
138
- parent_sampled = sampled_flag.nil? ? nil : sampled_flag != "0"
139
-
140
- [trace_id, parent_span_id, parent_sampled]
137
+ PropagationContext.extract_sentry_trace(sentry_trace)
141
138
  end
142
139
 
143
140
  # @return [Hash]
@@ -254,6 +251,8 @@ module Sentry
254
251
  @name = UNLABELD_NAME
255
252
  end
256
253
 
254
+ @profiler.stop
255
+
257
256
  if @sampled
258
257
  event = hub.current_client.event_from_transaction(self)
259
258
  hub.capture_event(event)
@@ -288,6 +287,13 @@ module Sentry
288
287
  @contexts[key] = value
289
288
  end
290
289
 
290
+ # Start the profiler.
291
+ # @return [void]
292
+ def start_profiler!
293
+ profiler.set_initial_sample_decision(sampled)
294
+ profiler.start
295
+ end
296
+
291
297
  protected
292
298
 
293
299
  def init_span_recorder(limit = 1000)
@@ -308,6 +314,7 @@ module Sentry
308
314
  items = {
309
315
  "trace_id" => trace_id,
310
316
  "sample_rate" => effective_sample_rate&.to_s,
317
+ "sampled" => sampled&.to_s,
311
318
  "environment" => @environment,
312
319
  "release" => @release,
313
320
  "public_key" => @dsn&.public_key
@@ -8,15 +8,15 @@ module Sentry
8
8
  # @return [<Array[Span]>]
9
9
  attr_accessor :spans
10
10
 
11
- # @return [Hash, nil]
12
- attr_accessor :dynamic_sampling_context
13
-
14
11
  # @return [Hash]
15
12
  attr_accessor :measurements
16
13
 
17
14
  # @return [Float, nil]
18
15
  attr_reader :start_timestamp
19
16
 
17
+ # @return [Hash, nil]
18
+ attr_accessor :profile
19
+
20
20
  def initialize(transaction:, **options)
21
21
  super(**options)
22
22
 
@@ -32,6 +32,8 @@ module Sentry
32
32
 
33
33
  finished_spans = transaction.span_recorder.spans.select { |span| span.timestamp && span != transaction }
34
34
  self.spans = finished_spans.map(&:to_hash)
35
+
36
+ populate_profile(transaction)
35
37
  end
36
38
 
37
39
  # Sets the event's start_timestamp.
@@ -49,5 +51,30 @@ module Sentry
49
51
  data[:measurements] = @measurements
50
52
  data
51
53
  end
54
+
55
+ private
56
+
57
+ def populate_profile(transaction)
58
+ profile_hash = transaction.profiler.to_hash
59
+ return if profile_hash.empty?
60
+
61
+ profile_hash.merge!(
62
+ environment: environment,
63
+ release: release,
64
+ timestamp: Time.at(start_timestamp).iso8601,
65
+ device: { architecture: Scope.os_context[:machine] },
66
+ os: { name: Scope.os_context[:name], version: Scope.os_context[:version] },
67
+ runtime: Scope.runtime_context,
68
+ transaction: {
69
+ id: event_id,
70
+ name: transaction.name,
71
+ trace_id: transaction.trace_id,
72
+ # TODO-neel-profiler stubbed for now, see thread_id note in profiler.rb
73
+ active_thead_id: '0'
74
+ }
75
+ )
76
+
77
+ self.profile = profile_hash
78
+ end
52
79
  end
53
80
  end
@@ -18,7 +18,8 @@ module Sentry
18
18
  :network_error,
19
19
  :sample_rate,
20
20
  :before_send,
21
- :event_processor
21
+ :event_processor,
22
+ :insufficient_data
22
23
  ]
23
24
 
24
25
  include LoggingHelper
@@ -143,7 +144,7 @@ module Sentry
143
144
  sent_at: Sentry.utc_now.iso8601
144
145
  }
145
146
 
146
- if event.is_a?(TransactionEvent) && event.dynamic_sampling_context
147
+ if event.is_a?(Event) && event.dynamic_sampling_context
147
148
  envelope_headers[:trace] = event.dynamic_sampling_context
148
149
  end
149
150
 
@@ -154,6 +155,13 @@ module Sentry
154
155
  event_payload
155
156
  )
156
157
 
158
+ if event.is_a?(TransactionEvent) && event.profile
159
+ envelope.add_item(
160
+ { type: 'profile', content_type: 'application/json' },
161
+ event.profile
162
+ )
163
+ end
164
+
157
165
  client_report_headers, client_report_payload = fetch_pending_client_report
158
166
  envelope.add_item(client_report_headers, client_report_payload) if client_report_headers
159
167
 
@@ -178,7 +186,7 @@ module Sentry
178
186
  reason, type = key
179
187
 
180
188
  # 'event' has to be mapped to 'error'
181
- category = type == 'transaction' ? 'transaction' : 'error'
189
+ category = type == 'event' ? 'error' : type
182
190
 
183
191
  { reason: reason, category: category, quantity: val }
184
192
  end
@@ -4,9 +4,15 @@ module Sentry
4
4
  module ArgumentCheckingHelper
5
5
  private
6
6
 
7
- def check_argument_type!(argument, expected_type)
8
- unless argument.is_a?(expected_type)
9
- raise ArgumentError, "expect the argument to be a #{expected_type}, got #{argument.class} (#{argument.inspect})"
7
+ def check_argument_type!(argument, *expected_types)
8
+ unless expected_types.any? { |t| argument.is_a?(t) }
9
+ raise ArgumentError, "expect the argument to be a #{expected_types.join(' or ')}, got #{argument.class} (#{argument.inspect})"
10
+ end
11
+ end
12
+
13
+ def check_argument_includes!(argument, values)
14
+ unless values.include?(argument)
15
+ raise ArgumentError, "expect the argument to be one of #{values.map(&:inspect).join(' or ')}, got #{argument.inspect}"
10
16
  end
11
17
  end
12
18
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sentry
4
- VERSION = "5.8.0"
4
+ VERSION = "5.12.0"
5
5
  end
data/lib/sentry-ruby.rb CHANGED
@@ -15,11 +15,13 @@ require "sentry/logger"
15
15
  require "sentry/event"
16
16
  require "sentry/error_event"
17
17
  require "sentry/transaction_event"
18
+ require "sentry/check_in_event"
18
19
  require "sentry/span"
19
20
  require "sentry/transaction"
20
21
  require "sentry/hub"
21
22
  require "sentry/background_worker"
22
23
  require "sentry/session_flusher"
24
+ require "sentry/cron/monitor_check_ins"
23
25
 
24
26
  [
25
27
  "sentry/rake",
@@ -73,8 +75,18 @@ module Sentry
73
75
  ##### Patch Registration #####
74
76
 
75
77
  # @!visibility private
76
- def register_patch(&block)
77
- registered_patches << block
78
+ def register_patch(patch = nil, target = nil, &block)
79
+ if patch && block
80
+ raise ArgumentError.new("Please provide either a patch and its target OR a block, but not both")
81
+ end
82
+
83
+ if block
84
+ registered_patches << block
85
+ else
86
+ registered_patches << proc do
87
+ target.send(:prepend, patch) unless target.ancestors.include?(patch)
88
+ end
89
+ end
78
90
  end
79
91
 
80
92
  # @!visibility private
@@ -420,6 +432,24 @@ module Sentry
420
432
  get_current_hub.capture_event(event)
421
433
  end
422
434
 
435
+ # Captures a check-in and sends it to Sentry via the currently active hub.
436
+ #
437
+ # @param slug [String] identifier of this monitor
438
+ # @param status [Symbol] status of this check-in, one of {CheckInEvent::VALID_STATUSES}
439
+ #
440
+ # @param [Hash] options extra check-in options
441
+ # @option options [String] check_in_id for updating the status of an existing monitor
442
+ # @option options [Integer] duration seconds elapsed since this monitor started
443
+ # @option options [Cron::MonitorConfig] monitor_config configuration for this monitor
444
+ #
445
+ # @yieldparam scope [Scope]
446
+ #
447
+ # @return [String, nil] The {CheckInEvent#check_in_id} to use for later updates on the same slug
448
+ def capture_check_in(slug, status, **options, &block)
449
+ return unless initialized?
450
+ get_current_hub.capture_check_in(slug, status, **options, &block)
451
+ end
452
+
423
453
  # Takes or initializes a new Sentry::Transaction and makes a sampling decision for it.
424
454
  #
425
455
  # @return [Transaction, nil]
@@ -479,6 +509,42 @@ module Sentry
479
509
  Scope.add_global_event_processor(&block)
480
510
  end
481
511
 
512
+ # Returns the traceparent (sentry-trace) header for distributed tracing.
513
+ # Can be either from the currently active span or the propagation context.
514
+ #
515
+ # @return [String, nil]
516
+ def get_traceparent
517
+ return nil unless initialized?
518
+ get_current_hub.get_traceparent
519
+ end
520
+
521
+ # Returns the baggage header for distributed tracing.
522
+ # Can be either from the currently active span or the propagation context.
523
+ #
524
+ # @return [String, nil]
525
+ def get_baggage
526
+ return nil unless initialized?
527
+ get_current_hub.get_baggage
528
+ end
529
+
530
+ # Returns the a Hash containing sentry-trace and baggage.
531
+ # Can be either from the currently active span or the propagation context.
532
+ #
533
+ # @return [Hash, nil]
534
+ def get_trace_propagation_headers
535
+ return nil unless initialized?
536
+ get_current_hub.get_trace_propagation_headers
537
+ end
538
+
539
+ # Continue an incoming trace from a rack env like hash.
540
+ #
541
+ # @param env [Hash]
542
+ # @return [Transaction, nil]
543
+ def continue_trace(env, **options)
544
+ return nil unless initialized?
545
+ get_current_hub.continue_trace(env, **options)
546
+ end
547
+
482
548
  ##### Helpers #####
483
549
 
484
550
  # @!visibility private
@@ -509,3 +575,4 @@ end
509
575
  # patches
510
576
  require "sentry/net/http"
511
577
  require "sentry/redis"
578
+ require "sentry/puma"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentry-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.8.0
4
+ version: 5.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sentry Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-06 00:00:00.000000000 Z
11
+ date: 2023-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -42,7 +42,6 @@ files:
42
42
  - ".rspec"
43
43
  - ".yardopts"
44
44
  - CHANGELOG.md
45
- - CODE_OF_CONDUCT.md
46
45
  - Gemfile
47
46
  - LICENSE.txt
48
47
  - Makefile
@@ -57,10 +56,14 @@ files:
57
56
  - lib/sentry/breadcrumb.rb
58
57
  - lib/sentry/breadcrumb/sentry_logger.rb
59
58
  - lib/sentry/breadcrumb_buffer.rb
59
+ - lib/sentry/check_in_event.rb
60
60
  - lib/sentry/client.rb
61
61
  - lib/sentry/configuration.rb
62
62
  - lib/sentry/core_ext/object/deep_dup.rb
63
63
  - lib/sentry/core_ext/object/duplicable.rb
64
+ - lib/sentry/cron/monitor_check_ins.rb
65
+ - lib/sentry/cron/monitor_config.rb
66
+ - lib/sentry/cron/monitor_schedule.rb
64
67
  - lib/sentry/dsn.rb
65
68
  - lib/sentry/envelope.rb
66
69
  - lib/sentry/error_event.rb
@@ -78,6 +81,9 @@ files:
78
81
  - lib/sentry/linecache.rb
79
82
  - lib/sentry/logger.rb
80
83
  - lib/sentry/net/http.rb
84
+ - lib/sentry/profiler.rb
85
+ - lib/sentry/propagation_context.rb
86
+ - lib/sentry/puma.rb
81
87
  - lib/sentry/rack.rb
82
88
  - lib/sentry/rack/capture_exceptions.rb
83
89
  - lib/sentry/rake.rb
data/CODE_OF_CONDUCT.md DELETED
@@ -1,74 +0,0 @@
1
- # Contributor Covenant Code of Conduct
2
-
3
- ## Our Pledge
4
-
5
- In the interest of fostering an open and welcoming environment, we as
6
- contributors and maintainers pledge to making participation in our project and
7
- our community a harassment-free experience for everyone, regardless of age, body
8
- size, disability, ethnicity, gender identity and expression, level of experience,
9
- nationality, personal appearance, race, religion, or sexual identity and
10
- orientation.
11
-
12
- ## Our Standards
13
-
14
- Examples of behavior that contributes to creating a positive environment
15
- include:
16
-
17
- * Using welcoming and inclusive language
18
- * Being respectful of differing viewpoints and experiences
19
- * Gracefully accepting constructive criticism
20
- * Focusing on what is best for the community
21
- * Showing empathy towards other community members
22
-
23
- Examples of unacceptable behavior by participants include:
24
-
25
- * The use of sexualized language or imagery and unwelcome sexual attention or
26
- advances
27
- * Trolling, insulting/derogatory comments, and personal or political attacks
28
- * Public or private harassment
29
- * Publishing others' private information, such as a physical or electronic
30
- address, without explicit permission
31
- * Other conduct which could reasonably be considered inappropriate in a
32
- professional setting
33
-
34
- ## Our Responsibilities
35
-
36
- Project maintainers are responsible for clarifying the standards of acceptable
37
- behavior and are expected to take appropriate and fair corrective action in
38
- response to any instances of unacceptable behavior.
39
-
40
- Project maintainers have the right and responsibility to remove, edit, or
41
- reject comments, commits, code, wiki edits, issues, and other contributions
42
- that are not aligned to this Code of Conduct, or to ban temporarily or
43
- permanently any contributor for other behaviors that they deem inappropriate,
44
- threatening, offensive, or harmful.
45
-
46
- ## Scope
47
-
48
- This Code of Conduct applies both within project spaces and in public spaces
49
- when an individual is representing the project or its community. Examples of
50
- representing a project or community include using an official project e-mail
51
- address, posting via an official social media account, or acting as an appointed
52
- representative at an online or offline event. Representation of a project may be
53
- further defined and clarified by project maintainers.
54
-
55
- ## Enforcement
56
-
57
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at stan001212@gmail.com. All
59
- complaints will be reviewed and investigated and will result in a response that
60
- is deemed necessary and appropriate to the circumstances. The project team is
61
- obligated to maintain confidentiality with regard to the reporter of an incident.
62
- Further details of specific enforcement policies may be posted separately.
63
-
64
- Project maintainers who do not follow or enforce the Code of Conduct in good
65
- faith may face temporary or permanent repercussions as determined by other
66
- members of the project's leadership.
67
-
68
- ## Attribution
69
-
70
- This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at [https://contributor-covenant.org/version/1/4][version]
72
-
73
- [homepage]: https://contributor-covenant.org
74
- [version]: https://contributor-covenant.org/version/1/4/