line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package PagerDuty::Agent; |
2
|
|
|
|
|
|
|
|
3
|
5
|
|
|
5
|
|
137180
|
use 5.010; |
|
5
|
|
|
|
|
40
|
|
4
|
5
|
|
|
5
|
|
20
|
use strict; |
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
79
|
|
5
|
5
|
|
|
5
|
|
17
|
use warnings; |
|
5
|
|
|
|
|
8
|
|
|
5
|
|
|
|
|
114
|
|
6
|
5
|
|
|
5
|
|
1926
|
use Data::Dump 'dump'; |
|
5
|
|
|
|
|
23914
|
|
|
5
|
|
|
|
|
269
|
|
7
|
5
|
|
|
5
|
|
1716
|
use Moo; |
|
5
|
|
|
|
|
36271
|
|
|
5
|
|
|
|
|
23
|
|
8
|
5
|
|
|
5
|
|
6856
|
use MooX::Types::MooseLike::Base qw/ ArrayRef Int Str /; |
|
5
|
|
|
|
|
26101
|
|
|
5
|
|
|
|
|
423
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = '0.02'; |
11
|
|
|
|
|
|
|
|
12
|
5
|
|
|
5
|
|
815
|
use English '-no_match_vars'; |
|
5
|
|
|
|
|
4065
|
|
|
5
|
|
|
|
|
36
|
|
13
|
5
|
|
|
5
|
|
3792
|
use HTTP::Request::Common 'POST'; |
|
5
|
|
|
|
|
78644
|
|
|
5
|
|
|
|
|
303
|
|
14
|
5
|
|
|
5
|
|
2617
|
use JSON; |
|
5
|
|
|
|
|
36777
|
|
|
5
|
|
|
|
|
33
|
|
15
|
5
|
|
|
5
|
|
3188
|
use LWP::UserAgent; |
|
5
|
|
|
|
|
91624
|
|
|
5
|
|
|
|
|
198
|
|
16
|
5
|
|
|
5
|
|
2165
|
use Sys::Hostname; |
|
5
|
|
|
|
|
4364
|
|
|
5
|
|
|
|
|
231
|
|
17
|
5
|
|
|
5
|
|
2002
|
use Time::Piece; |
|
5
|
|
|
|
|
29834
|
|
|
5
|
|
|
|
|
38
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 NAME |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
PagerDuty::Agent - A perl PagerDuty client |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 VERSION |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
Version 0.02 |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 SYNOPSIS |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
use PagerDuty::Agent; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
my $agent = PagerDuty::Agent->new( routing_key => '3fcc9112463424b599f996f9e780dfc6' ); |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
# trigger an event, then resolve it |
34
|
|
|
|
|
|
|
my $dedup_key = $agent->trigger_event( 'something is terribly wrong!' ); |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
if ( $dedup_key ) { |
37
|
|
|
|
|
|
|
print "Event created, dedup_key = $dedup_key\n"; |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
print "Event successfully resolved\n" |
40
|
|
|
|
|
|
|
if $agent->resolve_event( $dedup_key ); |
41
|
|
|
|
|
|
|
} else { |
42
|
|
|
|
|
|
|
warn "Failed to submit event: $@\n"; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
# additional context can be passed in |
46
|
|
|
|
|
|
|
$agent->trigger_event( |
47
|
|
|
|
|
|
|
summary => 'something is terribly wrong!', |
48
|
|
|
|
|
|
|
severity => 'critical', |
49
|
|
|
|
|
|
|
dedup_key => 'abc123', |
50
|
|
|
|
|
|
|
); |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
=head1 DESCRIPTION |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
This module implements the Events API for submitting events to PagerDuty. |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=head1 CONSTRUCTOR |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=head2 my $agent = PagerDuty::Agent->new( %options ) |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=over |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=item C<< routing_key => '3fcc9112463424b599f996f9e780dfc6' >> |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
The routing key or integration key associated with the API integration, found when |
65
|
|
|
|
|
|
|
viewing the service integration on the PagerDuty site. |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=item C<< timeout => 5 >> |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
Do not wait longer than this number of seconds when attempting to send an event. |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=item C<< api_version => 2 >> |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
Only version 2 is supported. |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=back |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=cut |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
has [qw/ post_url routing_key /] => ( |
80
|
|
|
|
|
|
|
is => 'ro', |
81
|
|
|
|
|
|
|
isa => Str, |
82
|
|
|
|
|
|
|
required => 1, |
83
|
|
|
|
|
|
|
); |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
has api_version => ( |
86
|
|
|
|
|
|
|
is => 'ro', |
87
|
|
|
|
|
|
|
isa => Int, |
88
|
|
|
|
|
|
|
default => 2, |
89
|
|
|
|
|
|
|
); |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
has timeout => ( |
92
|
|
|
|
|
|
|
is => 'ro', |
93
|
|
|
|
|
|
|
isa => Int, |
94
|
|
|
|
|
|
|
default => 5, |
95
|
|
|
|
|
|
|
); |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
has json_serializer => ( |
98
|
|
|
|
|
|
|
is => 'ro', |
99
|
|
|
|
|
|
|
builder => '_build_json_serializer', |
100
|
|
|
|
|
|
|
lazy => 1, |
101
|
|
|
|
|
|
|
); |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
has ua_obj => ( |
104
|
|
|
|
|
|
|
is => 'ro', |
105
|
|
|
|
|
|
|
builder => '_build_ua_obj', |
106
|
|
|
|
|
|
|
lazy => 1, |
107
|
|
|
|
|
|
|
); |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
has valid_severities => ( |
110
|
|
|
|
|
|
|
is => 'ro', |
111
|
|
|
|
|
|
|
isa => ArrayRef[Str], |
112
|
|
|
|
|
|
|
default => sub { [qw/ critical error warning info /] }, |
113
|
|
|
|
|
|
|
); |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
around BUILDARGS => sub { |
116
|
|
|
|
|
|
|
my ($orig, $class, %args) = @_; |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
my $routing_key = $args{routing_key} |
119
|
|
|
|
|
|
|
or die "must pass routing_key\n"; |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
delete($args{routing_key}); |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
my $timeout = delete($args{timeout}); |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
my $api_version = delete($args{api_version}); |
126
|
|
|
|
|
|
|
$api_version = 2 unless defined($api_version); |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
my $post_url = _post_url_for_version($api_version) |
129
|
|
|
|
|
|
|
or die "invalid api version $api_version\n"; |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
my $ua_obj = delete($args{ua_obj}); |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
return $class->$orig( |
134
|
|
|
|
|
|
|
routing_key => $routing_key, |
135
|
|
|
|
|
|
|
post_url => $post_url, |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
(defined($api_version) ? (api_version => $api_version) : ()), |
138
|
|
|
|
|
|
|
(defined($timeout) ? (timeout => $timeout) : ()), |
139
|
|
|
|
|
|
|
(defined($ua_obj) ? (ua_obj => $ua_obj) : ()), |
140
|
|
|
|
|
|
|
); |
141
|
|
|
|
|
|
|
}; |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
=head1 EVENT API |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
These methods are designed to create and manipulate events. |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=head2 my $dedup_key = $agent->trigger_event( $event_summary or %event ) |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
Trigger an event. The simple form accepts an $event_summary string with textual |
150
|
|
|
|
|
|
|
details of the event. The long form accepts additional event context. |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
When successful, returns the dedup_key. On error, returns undef and sets $@. |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
Event parameters when using the long form: |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=over |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=item C<< summary => 'Server is on fire' >> |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
Required. A textual description of the event. |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=item C<< class => 'cpu load' >> |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
The type of event. |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=item C<< component => 'mysql' >> |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
The mechanism responsible for the event. |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=item C<< custom_details => { user => 'me' } >> |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
A hash-ref of key value pairs containing any additional details. |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
=item C<< dedup_key => 'my unique identifier' >> |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
This is used for threading like events as well as identifying events already triggered. |
177
|
|
|
|
|
|
|
If this is not given, one will be generated by the upstream API. |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
=item C<< group => 'app-stack' >> |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
The grouping of components. |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=item C<< images => [ { src => 'https://img.memecdn.com/silly-humans_o_842106.jpg' } ] >> |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
One or more images, each specified as a hash-ref containing: |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=over |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
=item C<< src => 'image url' >> |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
Required. Must be HTTPS. |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
=item C<< href => 'link url' >> |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
Make the image link click-able. |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=item C<< alt => 'some alt text' >> |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
Add alt text to the image. |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=back |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=item C<< links => [ { text => 'see the docs', href => 'https://google.com' } ] >> |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
One or more links, each specified as a hash-ref containing: |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=over |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
=item C<< href => 'https://google.com' >> |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
Required. Link destination. |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=item C<< text => 'click here' >> |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
Required. Link text. |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
=back |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=item C<< severity => 'error' >> |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
The severity of the event. Can be one of critical, error, warning, or info. Defaults to error. |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
=item C<< source => 'google.com' >> |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
The hostname from which this event was triggered. Defaults to the current hostname. |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=item C<< timestamp => '2017-07-12T12:50:22.000-0700' >> |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
The event timestamp. This must be a valid ISO 8601 in the complete long form such as the |
230
|
|
|
|
|
|
|
example. This defaults to the current local time. |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
=back |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=cut |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
sub trigger_event { |
238
|
5
|
|
|
5
|
1
|
1827
|
my ($self, @params) = @_; |
239
|
|
|
|
|
|
|
|
240
|
5
|
100
|
|
|
|
19
|
@params = (summary => $params[0]) |
241
|
|
|
|
|
|
|
if scalar(@params) == 1; |
242
|
|
|
|
|
|
|
|
243
|
5
|
|
|
|
|
17
|
return $self->_post_event( |
244
|
|
|
|
|
|
|
$self->_format_pd_cef('trigger', @params), |
245
|
|
|
|
|
|
|
); |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
=head2 my $success = $agent->acknowledge_event( $dedup_key or %event ) |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
Acknowledge an existing event. The simple form accepts a $dedup_key. The long |
251
|
|
|
|
|
|
|
form accepts the same event parameters as C<< trigger_event >> except C<< summary >> |
252
|
|
|
|
|
|
|
is interpreted as the reason for acknowledging and C<< dedup_key >> is required. |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
When successful, returns the dedup_key. On error, returns undef and sets $@. |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=cut |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
sub acknowledge_event { |
259
|
2
|
|
|
2
|
1
|
1608
|
my ($self, @params) = @_; |
260
|
|
|
|
|
|
|
|
261
|
2
|
100
|
|
|
|
7
|
@params = (summary => 'no reason given', dedup_key => $params[0]) |
262
|
|
|
|
|
|
|
if scalar(@params) == 1; |
263
|
|
|
|
|
|
|
|
264
|
2
|
|
|
|
|
6
|
return $self->_post_event( |
265
|
|
|
|
|
|
|
$self->_format_pd_cef('acknowledge', @params), |
266
|
|
|
|
|
|
|
); |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
=head2 my $success = $agent->resolve_event( $dedup_key or %event ) |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
This accepts the same parameters as C<< acknowledge_event >> and returns the |
272
|
|
|
|
|
|
|
same values. |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=cut |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
sub resolve_event { |
277
|
2
|
|
|
2
|
1
|
1615
|
my ($self, @params) = @_; |
278
|
|
|
|
|
|
|
|
279
|
2
|
100
|
|
|
|
8
|
@params = (summary => 'no reason given', dedup_key => $params[0]) |
280
|
|
|
|
|
|
|
if scalar(@params) == 1; |
281
|
|
|
|
|
|
|
|
282
|
2
|
|
|
|
|
6
|
return $self->_post_event( |
283
|
|
|
|
|
|
|
$self->_format_pd_cef('resolve', @params), |
284
|
|
|
|
|
|
|
); |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
sub _post_event { |
288
|
9
|
|
|
9
|
|
984
|
my ($self, $event) = @_; |
289
|
|
|
|
|
|
|
|
290
|
9
|
50
|
|
|
|
22
|
unless ($event) { |
291
|
0
|
|
|
|
|
0
|
$EVAL_ERROR = "unable to parse event parameters"; |
292
|
0
|
|
|
|
|
0
|
warn "$EVAL_ERROR\n"; |
293
|
0
|
|
|
|
|
0
|
return; |
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
|
296
|
9
|
|
|
|
|
14
|
my ($response, $response_code, $response_content); |
297
|
|
|
|
|
|
|
|
298
|
9
|
|
|
|
|
11
|
eval { |
299
|
9
|
|
|
|
|
175
|
$self->ua_obj()->timeout($self->timeout()); |
300
|
|
|
|
|
|
|
|
301
|
9
|
|
|
|
|
4096
|
my $request = POST( |
302
|
|
|
|
|
|
|
$self->post_url(), |
303
|
|
|
|
|
|
|
'Content-Type' => 'application/json', |
304
|
|
|
|
|
|
|
'Authorization' => 'Token token='.$self->routing_key(), |
305
|
|
|
|
|
|
|
Content => $self->json_serializer()->encode($event), |
306
|
|
|
|
|
|
|
); |
307
|
8
|
|
|
|
|
9203
|
$response = $self->ua_obj()->request($request); |
308
|
|
|
|
|
|
|
|
309
|
8
|
|
|
|
|
6081
|
$response_code = $response->code(); |
310
|
8
|
|
|
|
|
62
|
$response_content = $response->content(); |
311
|
|
|
|
|
|
|
}; |
312
|
|
|
|
|
|
|
|
313
|
9
|
100
|
|
|
|
101
|
warn "$EVAL_ERROR\n" if $EVAL_ERROR; |
314
|
|
|
|
|
|
|
|
315
|
9
|
100
|
66
|
|
|
37
|
if ($response && $response->is_success()) { |
316
|
8
|
|
|
|
|
206
|
return $self->json_serializer()->decode($response_content)->{dedup_key}; |
317
|
|
|
|
|
|
|
} else { |
318
|
1
|
50
|
|
|
|
3
|
if ($response) { |
319
|
0
|
|
|
|
|
0
|
my $error_message; |
320
|
0
|
|
|
|
|
0
|
eval { |
321
|
0
|
|
|
|
|
0
|
$error_message = dump( |
322
|
|
|
|
|
|
|
$self->json_serializer()->decode($response_content) |
323
|
|
|
|
|
|
|
); |
324
|
|
|
|
|
|
|
}; |
325
|
|
|
|
|
|
|
|
326
|
0
|
0
|
|
|
|
0
|
$EVAL_ERROR = "Unable to parse response from PagerDuty: $error_message" |
327
|
|
|
|
|
|
|
if $error_message; |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
|
330
|
1
|
|
|
|
|
11
|
return; |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
sub _validate_severity { |
335
|
1
|
|
|
1
|
|
2
|
my ($self, $severity) = @_; |
336
|
|
|
|
|
|
|
|
337
|
1
|
50
|
|
|
|
4
|
return unless defined($severity); |
338
|
|
|
|
|
|
|
|
339
|
1
|
|
|
|
|
2
|
my %severity_hash = map { $_ => 1 } @{ $self->valid_severities() }; |
|
4
|
|
|
|
|
9
|
|
|
1
|
|
|
|
|
5
|
|
340
|
|
|
|
|
|
|
|
341
|
1
|
50
|
|
|
|
4
|
if (exists($severity_hash{$severity})) { |
342
|
1
|
|
|
|
|
2
|
return $severity; |
343
|
|
|
|
|
|
|
} else { |
344
|
0
|
|
|
|
|
0
|
warn "unknown severity: $severity\n"; |
345
|
0
|
|
|
|
|
0
|
return; |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
}; |
348
|
|
|
|
|
|
|
|
349
|
5
|
|
|
5
|
|
136
|
sub _build_json_serializer { JSON->new()->utf8(1)->pretty(1)->allow_nonref(1) } |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
sub _build_ua_obj { |
352
|
2
|
|
|
2
|
|
156
|
return LWP::UserAgent->new( |
353
|
|
|
|
|
|
|
keep_alive => 1, |
354
|
|
|
|
|
|
|
); |
355
|
|
|
|
|
|
|
} |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
sub _post_url_for_version { |
358
|
10
|
|
|
10
|
|
19
|
my ($version) = @_; |
359
|
10
|
50
|
|
|
|
22
|
return unless defined($version); |
360
|
|
|
|
|
|
|
return { |
361
|
|
|
|
|
|
|
2 => 'https://events.pagerduty.com/v2/enqueue', |
362
|
10
|
|
|
|
|
73
|
}->{$version}; |
363
|
|
|
|
|
|
|
} |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
sub _trim { |
366
|
0
|
|
|
0
|
|
0
|
my ($string, $length) = @_; |
367
|
0
|
0
|
|
|
|
0
|
return defined($string) |
368
|
|
|
|
|
|
|
? substr($string, 0, $length) |
369
|
|
|
|
|
|
|
: undef; |
370
|
|
|
|
|
|
|
} |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
sub _format_pd_cef { |
373
|
11
|
|
|
11
|
|
1519
|
my ($self, $event_action, @params) = @_; |
374
|
|
|
|
|
|
|
|
375
|
11
|
|
|
|
|
16
|
my %params; |
376
|
|
|
|
|
|
|
|
377
|
11
|
50
|
|
|
|
27
|
if (scalar(@params) % 2 == 0) { |
378
|
11
|
|
|
|
|
27
|
%params = @params; |
379
|
|
|
|
|
|
|
} else { |
380
|
0
|
|
|
|
|
0
|
return; |
381
|
|
|
|
|
|
|
} |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
$self->_validate_severity($params{severity}) |
384
|
11
|
100
|
|
|
|
34
|
if defined($params{severity}); |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
return { |
387
|
|
|
|
|
|
|
routing_key => $self->routing_key(), |
388
|
|
|
|
|
|
|
event_action => $event_action, |
389
|
|
|
|
|
|
|
dedup_key => $params{dedup_key}, |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
images => $params{images}, |
392
|
|
|
|
|
|
|
links => $params{links}, |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
payload => { |
395
|
|
|
|
|
|
|
summary => $params{summary}, |
396
|
|
|
|
|
|
|
source => $params{source} || hostname(), |
397
|
|
|
|
|
|
|
severity => $params{severity} || 'error', |
398
|
|
|
|
|
|
|
timestamp => $params{timestamp} || localtime()->strftime('%FT%T.000%z'), |
399
|
|
|
|
|
|
|
component => $params{component}, |
400
|
|
|
|
|
|
|
group => $params{group}, |
401
|
|
|
|
|
|
|
class => $params{class}, |
402
|
|
|
|
|
|
|
custom_details => $params{custom_details}, |
403
|
|
|
|
|
|
|
}, |
404
|
11
|
|
66
|
|
|
84
|
}; |
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
405
|
|
|
|
|
|
|
} |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
=head1 See Also |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
L<https://v2.developer.pagerduty.com/docs/events-api-v2> - The PagerDuty Events V2 API documentation |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
L<WebService::PagerDuty> - Another module implementing most of the PagerDuty Events V1 API. |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
=head1 LICENSE |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
Copyright (C) 2019 by Matt Harrington |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
The full text of this license can be found in the LICENSE file included with this module. |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
=cut |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
1; |