File Coverage

blib/lib/Sentry/Hub.pm
Criterion Covered Total %
statement 147 169 86.9
branch 6 12 50.0
condition 11 21 52.3
subroutine 29 31 93.5
pod 0 17 0.0
total 193 250 77.2


line stmt bran cond sub pod time code
1             use Mojo::Base -base, -signatures;
2 5     5   708651  
  5         39  
  5         35  
3             use Mojo::Util 'dumper';
4 5     5   1235 use Sentry::Hub::Scope;
  5         8  
  5         211  
5 5     5   1203 use Sentry::Logger 'logger';
  5         13  
  5         38  
6 5     5   2554 use Sentry::Severity;
  5         12  
  5         238  
7 5     5   31 use Sentry::Tracing::SamplingMethod;
  5         17  
  5         27  
8 5     5   2028 use Sentry::Tracing::Transaction;
  5         15  
  5         46  
9 5     5   146 use Sentry::Util qw(uuid4);
  5         12  
  5         43  
10 5     5   133 use Time::HiRes qw(time);
  5         9  
  5         205  
11 5     5   24 use Try::Tiny;
  5         9  
  5         58  
12 5     5   2893  
  5         5980  
  5         7102  
13             my $Instance;
14              
15             has _last_event_id => undef;
16             has _stack => sub { [{}] };
17             has client => undef;
18             has scopes => sub { [Sentry::Hub::Scope->new] };
19              
20             $Instance = Sentry::Hub->new($options);
21 0     0 0 0 }
  0         0  
  0         0  
  0         0  
22 0         0  
23             $self->scopes([Sentry::Hub::Scope->new]);
24             }
25 16     16 0 45  
  16         22  
  16         20  
26 16         91 $self->client($client);
27             $client->setup_integrations();
28             }
29 17     17 0 27  
  17         21  
  17         27  
  17         34  
30 17         74 return @{ $package->get_current_hub()->scopes }[-1];
31 17         439 }
32              
33             $Instance //= Sentry::Hub->new();
34 79     79 0 334 return $Instance;
  79         126  
  79         117  
35 79         98 }
  79         145  
36              
37             $cb->($self->get_current_scope);
38             }
39 195   66 195 0 20043  
40 195         522 my $scope = $self->get_current_scope->clone;
41             push $self->scopes->@*, $scope;
42             return $scope;
43 34     34 0 44 }
  34         38  
  34         37  
  34         36  
44 34         63  
45             my $scope = $self->push_scope;
46              
47 8     8 0 12 try {
  8         11  
  8         11  
48 8         53 $cb->($scope);
49 8         22 } finally {
50 8         40 $self->pop_scope;
51             };
52 8     8 0 12 }
  8         12  
  8         11  
  8         11  
  8         26  
53              
54 3     3 0 6 return $self->get_current_scope;
  3         7  
  3         5  
  3         7  
55 3         13 }
56              
57             my $client = $self->client;
58 3     3   219 my $scope = $self->get_current_scope;
59              
60 3     3   241 if ($client->can($method)) {
61 3         44 $client->$method(@args, $scope);
62             } else {
63             warn "Unknown method: $method";
64 5     5 0 63 }
  5         10  
  5         11  
65 5         25 }
66              
67             $self->_last_event_id(uuid4());
68 19     19   28 return $self->_last_event_id;
  19         29  
  19         22  
  19         31  
  19         23  
69 19         48 }
70 19         79  
71             $self, $message,
72 19 50       198 $level = Sentry::Severity->Info,
73 19         79 $hint = undef,
74             ) {
75 0         0 my $event_id = $self->_new_event_id();
76              
77             $self->_invoke_client('capture_message', $message, $level,
78             { ($hint // {})->%*, event_id => $event_id });
79 19     19   27  
  19         25  
  19         29  
80 19         77 return $event_id;
81 19         114 }
82              
83             $hint //= {};
84             my $event_id = $self->_new_event_id();
85 8         12  
  8         18  
86 8         13 $hint->{original_exception} = $exception;
87 8         11  
88 8     8 0 10 $self->_invoke_client('capture_exception', $exception,
  8         11  
89 8         22 { $hint->%*, event_id => $event_id });
90              
91 8   50     91 return $event_id;
92             }
93              
94 8         55 my $event_id = $self->_new_event_id();
95              
96             $self->_invoke_client('capture_event', $event,
97 2     2 0 6 { ($hint // {})->%*, event_id => $event_id });
  2         4  
  2         4  
  2         3  
  2         5  
98 2   50     16  
99 2         8 return $event_id;
100             }
101 2         11  
102             $self->get_current_scope->add_breadcrumb($crumb);
103 2         18 }
104              
105             $cb->($self);
106 2         25 }
107              
108             my $client = $self->client;
109 9     9 0 47 my $options = ($client && $client->get_options) // {};
  9         14  
  9         12  
  9         14  
  9         10  
110 9         28  
111             # nothing to do if there's no client or if tracing is disabled
112 9   50     112 if (!$client || !$options->{traces_sample_rate}) {
113             $transaction->sampled(0);
114             return $transaction;
115 9         58 }
116              
117             # if the user has forced a sampling decision by passing a `sampled` value in
118 8     8 0 707 # their transaction context, go with that
  8         14  
  8         16  
  8         14  
  8         15  
119 8         25 if (defined $transaction->sampled) {
120             $transaction->tags({
121             $transaction->tags->%*,
122 0     0 0 0 __sentry_samplingMethod => Sentry::Tracing::SamplingMethod->Explicit,
  0         0  
  0         0  
  0         0  
123 0         0 });
124              
125             return $transaction;
126 9     9 0 14 }
  9         15  
  9         15  
  9         12  
  9         12  
127 9         30  
128 9   33     70 my $sample_rate;
      50        
129              
130             if (defined $sampling_context->{parent_sampled}) {
131 9 50 33     111 $sample_rate = $sampling_context->{parent_sampled};
132 0         0 $transaction->tags({
133 0         0 $transaction->tags->%*,
134             __sentry_samplingMethod => Sentry::Tracing::SamplingMethod->Inheritance,
135             });
136             } else {
137             $sample_rate = $options->{traces_sample_rate};
138 9 50       38 $transaction->tags({
139 0         0 $transaction->tags->%*,
140             __sentry_samplingMethod => Sentry::Tracing::SamplingMethod->Rate,
141             __sentry_sampleRate => $sample_rate,
142             });
143             }
144 0         0  
145             if (!$sample_rate) {
146             logger->log(
147 9         68 'Discarding transaction because a negative sampling decision was inherited or tracesSampleRate is set to 0',
148             'Tracing'
149 9 50       23 );
150 0         0 $transaction->sampled(0);
151 0         0 return $transaction;
152             }
153              
154             # Now we roll the dice. Math.random is inclusive of 0, but not of 1, so
155             # strict < is safe here. In case sampleRate is a boolean, the < comparison
156 9         21 # will cause it to be automatically cast to 1 if it's true and 0 if it's
157 9         59 # false.
158             $transaction->sampled(rand() < $sample_rate);
159              
160             # if we're not going to keep it, we're done
161             if (!$transaction->sampled) {
162             logger->log(
163             "Discarding transaction because it's not included in the random sample (sampling rate = $sample_rate)",
164 9 50       61 'Tracing',
165 0         0 );
166             return $transaction;
167             }
168              
169 0         0 logger->log(
170 0         0 sprintf(
171             'Starting %s transaction - %s',
172             $transaction->op // '(unknown op)',
173             $transaction->name
174             ),
175             'Tracing',
176             );
177 9         48 return $transaction;
178             }
179              
180 9 50       58 my $transaction = Sentry::Tracing::Transaction->new(
181 0         0 { $context->%*, _hub => $self, start_timestamp => time });
182              
183             return $self->sample(
184             $transaction,
185 0         0 {
186             parent_sampled => $context->{parent_sampled},
187             ($custom_sampling_context // {})->%*,
188             }
189 9   50     65 );
190             }
191              
192             1;