logstash-output-scalyr 0.2.4.beta → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e192f378cc4b5209522208cf6191907f55b75dd8296e14dd752576de5caed7c
4
- data.tar.gz: 786ba490ef419bc0d65aa369362d5b5584969c7f6349ef5a510ac6b79d20bf61
3
+ metadata.gz: d304cddbc773ab520aac6f831897fc0ea1e00aef12f28528b31f388891048069
4
+ data.tar.gz: 970a67aef4939a74f2032f5aeefec859bb29b4fd4ec34955bb47d173427a1331
5
5
  SHA512:
6
- metadata.gz: 14ec39abfc55058e5a0ce58b2be1000268c74984be5c625d5b65521286af3e99c5f4a995f5c996d6ec2c8318084bfac8fec60c519a49700f045cce50fc17675a
7
- data.tar.gz: f06c9b47b63f8b95cdba01f60d376982cb85f5630971612487c9044f2e216e2b7aa01d750d8a340e45fea422dee27c93bbb0f3deb0c10656ac2af04ac6394f69
6
+ metadata.gz: 81535be5b8b2d5a377c09803e0af45a35e581b42c10b4576155f9482313bdc2a8d43444cf3ee886b825705507ca292f599326046cf4b1e516afb33979ac7de37
7
+ data.tar.gz: f0c566e5d739121926a5470258572386e0e587865e65499fac2dea040193d655283439faa4ebf72c38905f0a040db5a091cb0a1b45840e74f0360fc2c576a635
data/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Beta
2
2
 
3
+ ## 0.2.6.beta, 0.2.6
4
+
5
+ * Update default value of ``ssl_ca_bundle_path`` config option to
6
+ ``/etc/ssl/certs/ca-certificates.crt``. This way it works out of the box with the default
7
+ upstream logstash OSS Docker Image.
8
+ * Update default bundled root CA certs to contain all the root CA certs used by the DataSet API
9
+ endpoints.
10
+
11
+ In case you are encountering connectivity issues and SSL / TLS errors in the logstash log with
12
+ previous versions of the client you should upgrade to this release.
13
+
14
+ ## 0.2.5.beta
15
+
16
+ * Allow user to specify value for the DataSet event severity (``sev``) field. "sev" field is a
17
+ special top level event field which denotes the event severity (log level).
18
+
19
+ To enable this functionality, user needs to configure ``severity_field`` plugin config option and
20
+ set it to the logstash event field which carries the severity field value. This field value
21
+ needs to be an integer and contain a value from 0 to 6 (inclusive).
22
+ * Upgrade dependencies (manticore -> 0.9.1, jrjackson -> 0.4.15).
23
+ * Fix experimental ``zstandard`` support.
24
+
25
+ NOTE: For zstandard compression to be used zstd / libstd system package needs to be installed
26
+ (https://github.com/msievers/zstandard-ruby/#examples-for-installing-libzstd) and ``zstandard``
27
+ gem needs to be installed inside the Logstash jRuby environment
28
+ (e.g. ``/usr/share/logstash/bin/ruby -S /usr/share/logstash/vendor/jruby/bin/gem install
29
+ zstandard ; echo 'gem "zstandard"' >> /opt/logstash/Gemfile``).
30
+
3
31
  ## 0.2.4.beta
4
32
 
5
33
  * Experimental zstandard support - in development, not to be used in production.
data/Gemfile CHANGED
@@ -20,5 +20,5 @@ end
20
20
  gem 'pry'
21
21
  gem 'pry-nav'
22
22
  gem 'quantile', '~> 0.2.1'
23
- gem 'manticore', '~> 0.7.1', platform: :jruby
24
- gem 'jrjackson', '~> 0.4.14', platform: :jruby
23
+ gem 'manticore', '~> 0.9.1', platform: :jruby
24
+ gem 'jrjackson', '~> 0.4.15', platform: :jruby
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![CircleCI](https://circleci.com/gh/scalyr/logstash-output-scalyr.svg?style=svg)](https://circleci.com/gh/scalyr/logstash-output-scalyr) [![Gem Version](https://badge.fury.io/rb/logstash-output-scalyr.svg)](https://badge.fury.io/rb/logstash-output-scalyr)
1
+ [![Unit Tests & Lint](https://github.com/scalyr/logstash-output-scalyr/actions/workflows/unit_tests.yml/badge.svg)](https://github.com/scalyr/logstash-output-scalyr/actions/workflows/unit_tests.yml) [![Smoke Tests](https://github.com/scalyr/logstash-output-scalyr/actions/workflows/smoke_tests.yml/badge.svg)](https://github.com/scalyr/logstash-output-scalyr/actions/workflows/smoke_tests.yml) [![Micro Benchmarks](https://github.com/scalyr/logstash-output-scalyr/actions/workflows/microbenchmarks.yml/badge.svg)](https://github.com/scalyr/logstash-output-scalyr/actions/workflows/microbenchmarks.yml) [![Gem Version](https://badge.fury.io/rb/logstash-output-scalyr.svg)](https://badge.fury.io/rb/logstash-output-scalyr)
2
2
 
3
3
  # [Scalyr output plugin for Logstash]
4
4
 
@@ -6,12 +6,22 @@ This plugin implements a Logstash output plugin that uploads data to [Scalyr](ht
6
6
 
7
7
  You can view documentation for this plugin [on the Scalyr website](https://app.scalyr.com/solutions/logstash).
8
8
 
9
+ NOTE: If you are encountering connectivity issues and see SSL / TLS erros such as an example below,
10
+ you should upgrade to version 0.2.6 or higher.
11
+
12
+ ```javascript
13
+ {"message":"Error uploading to Scalyr (will backoff-retry)",
14
+ "error_class":"Manticore::ClientProtocolException","url":"https://agent.scalyr.com/addEvents",
15
+ "message":"PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed"
16
+ }
17
+ ```
18
+
9
19
  # Quick start
10
20
 
11
21
  1. Build the gem, run `gem build logstash-output-scalyr.gemspec`
12
- 2. Install the gem into a Logstash installation, run `/usr/share/logstash/bin/logstash-plugin install logstash-output-scalyr-0.2.3.gem`
22
+ 2. Install the gem into a Logstash installation, run `/usr/share/logstash/bin/logstash-plugin install logstash-output-scalyr-0.2.6.gem`
13
23
  or follow the latest official instructions on working with plugins from Logstash. As an alternative, you can directly install latest
14
- stable version from RubyGems - ``/usr/share/logstash/bin/logstash-plugin --version 0.2.3 logstash-output-scalyr``
24
+ stable version from RubyGems - ``/usr/share/logstash/bin/logstash-plugin --version 0.2.6 logstash-output-scalyr``
15
25
  3. Configure the output plugin (e.g. add it to a pipeline .conf)
16
26
  4. Restart Logstash
17
27
 
@@ -86,6 +96,79 @@ output {
86
96
  }
87
97
  ```
88
98
 
99
+ ## Notes on severity (sev) attribute handling
100
+
101
+ ``sev`` is a special top level DataSet event field which denotes the event severity / log level.
102
+
103
+ To enable this functionality, user needs to define ``severity_field`` plugin config option. This
104
+ config option tells the plugin which Logstash event field carries the value for the severity field.
105
+
106
+ The actual value needs to be an integer between 0 and 6 inclusive. Those values are mapped to
107
+ different severity / log levels on DataSet server side as shown below:
108
+
109
+ - 0 -> finest
110
+ - 1 -> trace
111
+ - 2 -> debug
112
+ - 3 -> info
113
+ - 4 -> warning
114
+ - 5 -> error
115
+ - 6 -> fatal / emergency / critical
116
+
117
+ ```
118
+ output {
119
+ scalyr {
120
+ api_write_token => 'SCALYR_API_KEY'
121
+ ...
122
+ severity_field => 'severity'
123
+ }
124
+ }
125
+ ```
126
+
127
+ In the example above, value for the DataSet severity field should be included in the ``severity``
128
+ Logstash event field.
129
+
130
+ In case the field value doesn't contain a valid severity number (0 - 6), ``sev`` field won't be
131
+ set on the event object to prevent API from rejecting an invalid request.
132
+
133
+ ## Note On Server SSL Certificate Validation
134
+
135
+ By default when validating DataSet endpoint server SSL certificate, logstash plugin will use a
136
+ combination of system CA certs bundle from ``/etc/ssl/certs/ca-certificates.crt`` and combination
137
+ of root CA certificates which are bundled with this plugin which represent root certificates used
138
+ to issue / sign server certificates used by the DataSet API endpoint.
139
+
140
+ In case you want to use only system CA certs bundle (not use certs which are bundled with the
141
+ plugin), you can do that by using the following config options:
142
+
143
+ ```
144
+ output {
145
+ scalyr {
146
+ api_write_token => 'SCALYR_API_KEY'
147
+ ...
148
+ # You only need to set this config option in case default CA bundle path on your system is
149
+ # different
150
+ ssl_ca_bundle_path => "/etc/ssl/certs/ca-certificates.crt"
151
+ append_builtin_cert => false
152
+ }
153
+ }
154
+ ```
155
+
156
+ In case you want to use only root CA certs which are bundled with the plugin (not use system CA
157
+ certs bundle), you can do that by using the following config options:
158
+
159
+ ```
160
+ output {
161
+ scalyr {
162
+ api_write_token => 'SCALYR_API_KEY'
163
+ ...
164
+ # You only need to set this config option in case default CA bundle path on your system is
165
+ # different
166
+ ssl_ca_bundle_path => nil
167
+ append_builtin_cert => true
168
+ }
169
+ }
170
+ ```
171
+
89
172
  ## Options
90
173
 
91
174
  - The Scalyr API write token, these are available at https://www.scalyr.com/keys. This is the only compulsory configuration field required for proper upload
@@ -100,9 +183,13 @@ output {
100
183
 
101
184
  ---
102
185
 
103
- - Path to SSL bundle file.
186
+ - Path to SSL CA bundle file which is used to verify the server certificate.
187
+
188
+ `config :ssl_ca_bundle_path, :validate => :string, :default => "/etc/ssl/certs/ca-certificates.crt"`
104
189
 
105
- `config :ssl_ca_bundle_path, :validate => :string, :default => nil`
190
+ If for some reason you need to disable server cert validation (you are strongly recommended to
191
+ not disable it unless specifically instructed to do so or have a valid reason for it), you can do
192
+ that by setting ``ssl_verify_peer`` config option to false.
106
193
 
107
194
  ---
108
195
 
@@ -477,7 +564,7 @@ git clone https://github.com/Kami/logstash-config-tester ~/
477
564
  gem build logstash-output-scalyr.gemspec
478
565
 
479
566
  # 2. Copy it to the config test repo
480
- cp logstash-output-scalyr-0.2.3.gem ~/logstash-config-test/logstash-output-scalyr.gem
567
+ cp logstash-output-scalyr-0.2.6.gem ~/logstash-config-test/logstash-output-scalyr.gem
481
568
 
482
569
  # 3. Build docker image with the latest dev version of the plugin (may take a while)
483
570
  docker-compose build
@@ -60,6 +60,22 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
60
60
  # (Warning: events with an existing 'logfile' field, it will be overwritten)
61
61
  config :logfile_field, :validate => :string, :default => 'logfile'
62
62
 
63
+ # Record field which includes the value for the "severity" field. severity is a special field which tells
64
+ # Scalyr severity / log level for a particulat event. This field is a top level event field and not
65
+ # event attribute field. Actual field value must be an integer and is mapped to different severity /
66
+ # log level on DataSet server side as shown below:
67
+ #
68
+ # - 0 -> finest
69
+ # - 1 -> trace
70
+ # - 2 -> debug
71
+ # - 3 -> info
72
+ # - 4 -> warning
73
+ # - 5 -> error
74
+ # - 6 -> fatal / emergency / critical
75
+ #
76
+ # By default, if Event contains no severity field, default value of 3 (info) will be used.
77
+ config :severity_field, :validate => :string, :default => nil
78
+
63
79
  # The Scalyr Output Plugin expects the main log message to be contained in the Event['message']. If your main log
64
80
  # content is contained in a different field, specify it here. It will be renamed to 'message' before upload.
65
81
  # (Warning: events with an existing 'message' field, it will be overwritten)
@@ -118,7 +134,9 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
118
134
  config :ssl_verify_peer, :validate => :boolean, :default => true
119
135
 
120
136
  # Path to SSL bundle file.
121
- config :ssl_ca_bundle_path, :validate => :string, :default => "/etc/ssl/certs/ca-bundle.crt"
137
+ # Technically, we could also use Ruby specific cert store + using OpenSSL::X509::DEFAULT_CERT_FILE
138
+ # here, although that variable stores der and not pem format.
139
+ config :ssl_ca_bundle_path, :validate => :string, :default => "/etc/ssl/certs/ca-certificates.crt"
122
140
 
123
141
  # If we should append our built-in Scalyr cert to the one we find at `ssl_ca_bundle_path`.
124
142
  config :append_builtin_cert, :validate => :boolean, :default => true
@@ -130,7 +148,8 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
130
148
  # Valid options are bz2, deflate, or none.
131
149
  config :compression_type, :validate => :string, :default => 'deflate'
132
150
 
133
- # An int containing the compression level of compression to use, from 1-9. Defaults to 6
151
+ # An int containing the compression level of compression to use, from 1-9. Defaults to 6. Only
152
+ # applicable when compression type is "deflate" or "bz2".
134
153
  config :compression_level, :validate => :number, :default => 6
135
154
 
136
155
  # How often to log and report status metrics to Scalyr. Defaults to every 5
@@ -495,9 +514,9 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
495
514
  :will_retry_in_seconds => sleep_interval,
496
515
  }
497
516
  exc_data[:code] = e.code if e.code
498
- if @logger.debug? and e.body
517
+ if @logger.debug? and defined?(e.body) and e.body
499
518
  exc_data[:body] = e.body
500
- elsif e.body
519
+ elsif defined?(e.body) and e.body
501
520
  exc_data[:body] = Scalyr::Common::Util.truncate(e.body, 512)
502
521
  end
503
522
  exc_data[:payload] = "\tSample payload: #{request[:body][0,1024]}..." if @logger.debug?
@@ -722,6 +741,11 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
722
741
  # Rename user-specified logfile field -> 'logfile'
723
742
  rename.call(@logfile_field, 'logfile')
724
743
 
744
+ # Rename user-specified severity field -> 'severity' (if configured)
745
+ if not @severity_field.nil?
746
+ rename.call(@severity_field, 'severity')
747
+ end
748
+
725
749
  # Remove "host" attribute
726
750
  if @remove_host_attribute_from_events and record.key? "host"
727
751
  record.delete("host")
@@ -766,6 +790,7 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
766
790
  logs[log_identifier]['attrs']['logfile'] = record['logfile']
767
791
  record.delete('logfile')
768
792
  end
793
+
769
794
  if @log_constants
770
795
  @log_constants.each {|log_constant|
771
796
  if record.key? log_constant
@@ -827,6 +852,21 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
827
852
  end
828
853
  end
829
854
 
855
+ severity = record['severity']
856
+ severity_int = nil
857
+
858
+ # Server won't accept the payload in case severity value is not valid. To avoid events from
859
+ # being dropped, we only set Event.sev field in case this field contains a valid value.
860
+ if not @severity_field.nil? and severity and severity.is_integer?
861
+ severity_int = severity.to_i
862
+
863
+ if severity_int >= 0 and severity_int <= 6
864
+ record.delete('severity')
865
+ else
866
+ severity_int = nil
867
+ end
868
+ end
869
+
830
870
  # Use LogStash event.timestamp as the 'ts' Scalyr timestamp. Note that this may be overwritten by input
831
871
  # filters so may not necessarily reflect the actual originating timestamp.
832
872
  scalyr_event = {
@@ -840,6 +880,11 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
840
880
  scalyr_event[:log] = logs_ids[log_identifier]
841
881
  end
842
882
 
883
+ # optionally set severity (if available and valid)
884
+ if @severity_field and not severity_int.nil?
885
+ scalyr_event[:sev] = severity_int
886
+ end
887
+
843
888
  if @estimate_each_event_size
844
889
  # get json string of event to keep track of how many bytes we are sending
845
890
  begin
@@ -1104,7 +1149,7 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
1104
1149
  begin
1105
1150
  client_session.post_add_events(multi_event_request[:body], true, 0)
1106
1151
  rescue => e
1107
- if e.body
1152
+ if defined?(e.body) and e.body
1108
1153
  @logger.warn(
1109
1154
  "Unexpected error occurred while uploading status to Scalyr",
1110
1155
  :error_message => e.message,
@@ -1170,3 +1215,15 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
1170
1215
  !execution_context.dlq_writer.inner_writer.is_a?(::LogStash::Util::DummyDeadLetterQueueWriter)
1171
1216
  end
1172
1217
  end
1218
+
1219
+ class String
1220
+ def is_integer?
1221
+ self.to_i.to_s == self
1222
+ end
1223
+ end
1224
+
1225
+ class Integer
1226
+ def is_integer?
1227
+ true
1228
+ end
1229
+ end
@@ -0,0 +1,25 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
3
+ MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
4
+ GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
5
+ YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
6
+ MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
7
+ BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
8
+ GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
9
+ ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
10
+ BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
11
+ 3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
12
+ YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
13
+ rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
14
+ ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
15
+ oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
16
+ MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
17
+ QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
18
+ b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
19
+ AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
20
+ GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
21
+ Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
22
+ G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
23
+ l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
24
+ smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
25
+ -----END CERTIFICATE-----
@@ -0,0 +1,126 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
32
+ -----BEGIN CERTIFICATE-----
33
+ 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
62
+ -----END CERTIFICATE-----
63
+ -----BEGIN CERTIFICATE-----
64
+ MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
65
+ MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
66
+ GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
67
+ YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
68
+ MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
69
+ BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
70
+ GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
71
+ ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
72
+ BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
73
+ 3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
74
+ YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
75
+ rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
76
+ ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
77
+ oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
78
+ MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
79
+ QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
80
+ b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
81
+ AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
82
+ GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
83
+ Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
84
+ G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
85
+ l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
86
+ smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
87
+ -----END CERTIFICATE-----
88
+ -----BEGIN CERTIFICATE-----
89
+ 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
126
+ -----END CERTIFICATE-----
@@ -0,0 +1,31 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
@@ -0,0 +1,31 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
@@ -0,0 +1,39 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
39
+ -----END CERTIFICATE-----
@@ -76,46 +76,7 @@ class ClientSession
76
76
  @pool_max_per_route = pool_max_per_route
77
77
 
78
78
  # A cert to use by default to avoid issues caused by the OpenSSL library not validating certs according to standard
79
- @cert_string = "" \
80
- "-----BEGIN CERTIFICATE-----\n" \
81
- "MIIG6zCCBNOgAwIBAgIJAM5aknNWtN6oMA0GCSqGSIb3DQEBCwUAMIGpMQswCQYD\n" \
82
- "VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEXMBUGA1UEBxMOUG9ydG9sYSBW\n" \
83
- "YWxsZXkxEzARBgNVBAoTClNjYWx5ciBJbmMxFTATBgNVBAsTDFNjYWx5ciBBZ2Vu\n" \
84
- "dDEdMBsGA1UEAxMUU2NhbHlyIEFnZW50IENBIFJvb3QxITAfBgkqhkiG9w0BCQEW\n" \
85
- "EmNvbnRhY3RAc2NhbHlyLmNvbTAeFw0xNDA5MDkyMTUyMDVaFw0yNDA5MDYyMTUy\n" \
86
- "MDVaMIGpMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEXMBUGA1UE\n" \
87
- "BxMOUG9ydG9sYSBWYWxsZXkxEzARBgNVBAoTClNjYWx5ciBJbmMxFTATBgNVBAsT\n" \
88
- "DFNjYWx5ciBBZ2VudDEdMBsGA1UEAxMUU2NhbHlyIEFnZW50IENBIFJvb3QxITAf\n" \
89
- "BgkqhkiG9w0BCQEWEmNvbnRhY3RAc2NhbHlyLmNvbTCCAiIwDQYJKoZIhvcNAQEB\n" \
90
- "BQADggIPADCCAgoCggIBALdNamcMNVxkIB6qVWmNCi1jeyeqOX00rYAWDlyBHff7\n" \
91
- "vU833Evuixgrf0HxrOQNiPsOK66ehG6LfJd2UIBDEHBCXRo+aeFQLrCLIVXiqJ2W\n" \
92
- "Tvl7dUU9d7zfw/XXif3lMQTiyQAWYTyjfugDczEScEUk93EWFfW47j9PTGh96yKm\n" \
93
- "nVbfOxD4XbN0ykdo85cs7M/NOHQj4q34l77XGXrit+nb1cL3wS9ZzJG8s40J2+Dp\n" \
94
- "LUA8KBQuvim6hfqrjaDX0bXVvc52a7TSh/zb58gkLbiqvBuPo5P8PBLHCx8bJtZu\n" \
95
- "fjWRdjaftgw7CcsdIuMhbm3823WI/A+/p4s1B5KOPqOYRkgG8FBqFIRTecKAV5wC\n" \
96
- "Z2ruTytoOUBWItrheyJhm+99X1I2y/6mdecBdk7j3+8U+nCsGHkH5Jwjl2BH9tfT\n" \
97
- "RUhVTCQs25XLNm41kZo7xK464xZsJKHXj9jr5gLIdF6CgzU2uYsQHKcw1pAVITLe\n" \
98
- "bfGEob8AcL0E7+1hurRjyYxtxZpsZeGMwI0/BStT+fLEAOJ1byGUgSUbhi9lJ8Hc\n" \
99
- "+NZDfaCaCZKRxjePCqeWjZUUdVoH3fNSi2GuNLqtOFzxlkP5tBErnXufE6XZAtEQ\n" \
100
- "lv/9qxa4ZLsvhbt+6qQryIAHL4aReh/VReER438ARdwG2QDK+vRfhNpke69em5Kb\n" \
101
- "AgMBAAGjggESMIIBDjAdBgNVHQ4EFgQUENX6MjnzqTJdTQMAEakSdXV/I80wgd4G\n" \
102
- "A1UdIwSB1jCB04AUENX6MjnzqTJdTQMAEakSdXV/I82hga+kgawwgakxCzAJBgNV\n" \
103
- "BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRcwFQYDVQQHEw5Qb3J0b2xhIFZh\n" \
104
- "bGxleTETMBEGA1UEChMKU2NhbHlyIEluYzEVMBMGA1UECxMMU2NhbHlyIEFnZW50\n" \
105
- "MR0wGwYDVQQDExRTY2FseXIgQWdlbnQgQ0EgUm9vdDEhMB8GCSqGSIb3DQEJARYS\n" \
106
- "Y29udGFjdEBzY2FseXIuY29tggkAzlqSc1a03qgwDAYDVR0TBAUwAwEB/zANBgkq\n" \
107
- "hkiG9w0BAQsFAAOCAgEAmmgm1AeO7wfuR36HHgpZCKZxboRFwc2FzKaHNSg2FQ0G\n" \
108
- "MuOP6HZUQWsaXLe0Kc8emJKrIwrn6x2jMm19Bjbps2bPW6ao6UE/6fb5Z7CX82IX\n" \
109
- "pKlDDH6OfYjDplBzoqf5PkPgxZNyiZ7nyNUWz+P2vesLFVynmej2MvLIZVnEJ2Wp\n" \
110
- "xzyHMKQo92DP8yNEudoK8QQpoLcuNcAli9blt8+NIV9RSDrI9CvArLNpZJMlS1Vx\n" \
111
- "gdzEU3wEQYWc36j3XCsp7ZDvgTm6FpyHS5ccMpXR1E62tVINGX9r+97ZHyxjqurb\n" \
112
- "606y1FzV/5Mf/aihPYSSreq63UVqdsaQfyS77Q4tpJofq875w8nd2Vs3guDs2T0h\n" \
113
- "1bOlV3e2HfglWsHKwNguQZo2nfMUp11IYfV/HOKWNQkbrPhuayXMi3i2wCZe9JNt\n" \
114
- "P9uZ2OjzsVu2QFcSlvZF6y02/bjbNATRfj/J/SHNFyCDu6bXhtAu0yZzFLiOZxjD\n" \
115
- "LwzunBMoWcJj+P2Vx3OhbE9FMyMeKdOWdTgiI1GLEkfJi6s7d/tk1ayLmbBTRD/e\n" \
116
- "XkjSeLBss6mA1INuE1+gKVA4MABsUiLqGZ8xCPN16CyPcTqL2TJFo1IOqivMxKDh\n" \
117
- "H4Z/mHoGi5SRnye+Wo+jyiQiWjJQ5LrlQPbHmuO0tLs9lM1t9nhzLifzga5F4+o=\n" \
118
- "-----END CERTIFICATE-----"
79
+ @cert_string = CA_CERT_STRING
119
80
 
120
81
  # Request statistics are accumulated across multiple threads and must be accessed through a mutex
121
82
  @stats_lock = Mutex.new
@@ -159,18 +120,40 @@ class ClientSession
159
120
  # verify peers to prevent potential MITM attacks
160
121
  if @ssl_verify_peer
161
122
  c[:ssl][:verify] = :strict
162
- @ca_cert = Tempfile.new("ca_cert")
163
- if File.file?(@ssl_ca_bundle_path)
164
- @ca_cert.write(File.read(@ssl_ca_bundle_path))
165
- @ca_cert.flush
166
- end
167
- if @append_builtin_cert
168
- open(@ca_cert.path, 'a') do |f|
123
+
124
+ if not @append_builtin_cert
125
+ # System CA bundle is used, no need to copy it over and append our bundled CA cert
126
+ @logger.info("Using CA bundle from #{@ssl_ca_bundle_path} to validate the server side certificate")
127
+ @ca_cert_path = @ssl_ca_bundle_path
128
+
129
+ if not File.file?(@ssl_ca_bundle_path)
130
+ # TODO: For now we don't throw to keep code backward compatible. In the future in case
131
+ # file doesn't exist, we should throw instead of write empty CA cert file and pass that
132
+ # to Manticore which will eventually fail and throw on cert validation
133
+ #raise Errno::ENOENT.new("ssl_ca_bundle_path config option to an invalid file path which doesn't exist - #{@ssl_ca_bundle_path}")
134
+ @ca_cert = Tempfile.new("ca_cert")
135
+ @ca_cert_path = @ca_cert.path
136
+ end
137
+ else
138
+ @ca_cert = Tempfile.new("ca_cert")
139
+
140
+ if File.file?(@ssl_ca_bundle_path)
141
+ @ca_cert.write(File.read(@ssl_ca_bundle_path))
142
+ @ca_cert.flush
143
+ else
144
+ @logger.warn("CA bundle (#{@ssl_ca_bundle_path}) doesn't exist, using only bundled CA certificates")
145
+ end
146
+
147
+ open(@ca_cert.path, "a") do |f|
169
148
  f.puts @cert_string
170
149
  end
150
+
151
+ @ca_cert.flush
152
+ @ca_cert_path = @ca_cert.path
153
+
154
+ @logger.info("Using CA bundle from #{@ssl_ca_bundle_path} combined with bundled certificates to validate the server side certificate (#{@ca_cert_path})")
171
155
  end
172
- @ca_cert.flush
173
- c[:ssl][:ca_file] = @ca_cert.path
156
+ c[:ssl][:ca_file] = @ca_cert_path
174
157
  else
175
158
  c[:ssl][:verify] = :disable
176
159
  end
@@ -305,13 +288,13 @@ class ClientSession
305
288
  # don't directly depend on this gem and it's up to the user to install
306
289
  # both dependencies manually in case they want to use zstandard.
307
290
  begin
308
- gem 'zstandard'
291
+ require 'zstandard'
309
292
  rescue LoadError
310
293
  raise SystemExit, "zstandard gem is missing. If you want to use zstandard compression you need to make sure zstandard and and libzstd dependency is installed. See TODO for more information."
311
294
  end
312
295
 
313
296
  encoding = 'zstandard'
314
- compressed_body = Zstandard.deflate(string)
297
+ compressed_body = Zstandard.deflate(body)
315
298
  end
316
299
  end_time = Time.now.to_f
317
300
  compression_duration = end_time - start_time
@@ -1,5 +1,15 @@
1
1
  # encoding: utf-8
2
- PLUGIN_VERSION = "v0.2.4.beta"
2
+
3
+ PLUGIN_VERSION = "v0.2.6"
3
4
 
4
5
  # Special event level attribute name which can be used for setting event level serverHost attribute
5
6
  EVENT_LEVEL_SERVER_HOST_ATTRIBUTE_NAME = '__origServerHost'
7
+
8
+ # Path to the bundled root CA certs used to sign server cert
9
+ CA_CERT_PATH = File.expand_path(File.join(File.dirname(__FILE__), + "/certs/ca_certs.crt"))
10
+
11
+ # Cert which is append to a copy of "/etc/ssl/certs/ca-bundle.crt" file.
12
+ # This is done for backward compatibility and convenience reasons when "appending_builtin_cert"
13
+ # plugin config option is set to true - eventually we want to default it to false and just rely
14
+ # on system ca bundle by default.
15
+ CA_CERT_STRING = File.read(CA_CERT_PATH)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-output-scalyr'
3
- s.version = '0.2.4.beta'
3
+ s.version = '0.2.6'
4
4
  s.licenses = ['Apache-2.0']
5
5
  s.summary = "Scalyr output plugin for Logstash"
6
6
  s.description = "Sends log data collected by Logstash to Scalyr (https://www.scalyr.com)"
@@ -39,6 +39,9 @@ describe LogStash::Outputs::Scalyr do
39
39
  plugin = LogStash::Outputs::Scalyr.new({
40
40
  'api_write_token' => '1234',
41
41
  'perform_connectivity_check' => false,
42
+ 'max_retries' => 2,
43
+ 'retry_max_interval' => 2,
44
+ 'retry_initial_interval' => 0.2,
42
45
  })
43
46
  plugin.register
44
47
  plugin.instance_variable_set(:@running, false)
@@ -54,7 +57,7 @@ describe LogStash::Outputs::Scalyr do
54
57
  :record_count=>3,
55
58
  :total_batches=>1,
56
59
  :url=>"https://agent.scalyr.com/addEvents",
57
- :will_retry_in_seconds=>2,
60
+ :will_retry_in_seconds=>0.4,
58
61
  :body=>"{\n \"message\": \"Couldn't decode API token ...234.\",\n \"status\": \"error/client/badParam\"\n}"
59
62
  }
60
63
  )
@@ -68,6 +71,9 @@ describe LogStash::Outputs::Scalyr do
68
71
  'perform_connectivity_check' => false,
69
72
  'ssl_ca_bundle_path' => '/fakepath/nocerts',
70
73
  'append_builtin_cert' => false,
74
+ 'max_retries' => 2,
75
+ 'retry_max_interval' => 2,
76
+ 'retry_initial_interval' => 0.2,
71
77
  })
72
78
  plugin.register
73
79
  plugin.instance_variable_set(:@running, false)
@@ -77,12 +83,13 @@ describe LogStash::Outputs::Scalyr do
77
83
  {
78
84
  :error_class=>"Manticore::UnknownException",
79
85
  :batch_num=>1,
80
- :message=>"java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty",
86
+ :message=>"Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty",
87
+ #:message=>"java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty",
81
88
  :payload_size=>737,
82
89
  :record_count=>3,
83
90
  :total_batches=>1,
84
91
  :url=>"https://agent.scalyr.com/addEvents",
85
- :will_retry_in_seconds=>2
92
+ :will_retry_in_seconds=>0.4
86
93
  }
87
94
  )
88
95
  end
@@ -98,6 +105,9 @@ describe LogStash::Outputs::Scalyr do
98
105
  'api_write_token' => '1234',
99
106
  'perform_connectivity_check' => false,
100
107
  'append_builtin_cert' => false,
108
+ 'max_retries' => 2,
109
+ 'retry_max_interval' => 2,
110
+ 'retry_initial_interval' => 0.2,
101
111
  })
102
112
  plugin.register
103
113
  plugin.instance_variable_set(:@running, false)
@@ -107,12 +117,13 @@ describe LogStash::Outputs::Scalyr do
107
117
  {
108
118
  :error_class=>"Manticore::UnknownException",
109
119
  :batch_num=>1,
110
- :message=>"java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty",
120
+ :message=>"Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty",
121
+ #:message=>"java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty",
111
122
  :payload_size=>737,
112
123
  :record_count=>3,
113
124
  :total_batches=>1,
114
125
  :url=>"https://agent.scalyr.com/addEvents",
115
- :will_retry_in_seconds=>2
126
+ :will_retry_in_seconds=>0.4
116
127
  }
117
128
  )
118
129
  end
@@ -141,6 +152,9 @@ describe LogStash::Outputs::Scalyr do
141
152
  'api_write_token' => '1234',
142
153
  'perform_connectivity_check' => false,
143
154
  'scalyr_server' => 'https://invalid.mitm.should.fail.test.agent.scalyr.com:443',
155
+ 'max_retries' => 2,
156
+ 'retry_max_interval' => 2,
157
+ 'retry_initial_interval' => 0.2,
144
158
  })
145
159
  plugin.register
146
160
  plugin.instance_variable_set(:@running, false)
@@ -150,12 +164,12 @@ describe LogStash::Outputs::Scalyr do
150
164
  {
151
165
  :error_class=>"Manticore::UnknownException",
152
166
  :batch_num=>1,
153
- :message=>"Host name 'invalid.mitm.should.fail.test.agent.scalyr.com' does not match the certificate subject provided by the peer (CN=*.scalyr.com)",
167
+ :message=>"Certificate for <invalid.mitm.should.fail.test.agent.scalyr.com> doesn't match any of the subject alternative names: [*.scalyr.com, scalyr.com]",
154
168
  :payload_size=>737,
155
169
  :record_count=>3,
156
170
  :total_batches=>1,
157
171
  :url=>"https://invalid.mitm.should.fail.test.agent.scalyr.com/addEvents",
158
- :will_retry_in_seconds=>2
172
+ :will_retry_in_seconds=>0.4
159
173
  }
160
174
  )
161
175
  ensure
@@ -171,9 +185,11 @@ describe LogStash::Outputs::Scalyr do
171
185
  plugin = LogStash::Outputs::Scalyr.new({
172
186
  'api_write_token' => '1234',
173
187
  'perform_connectivity_check' => false,
174
- 'retry_initial_interval' => 0.1,
175
188
  'ssl_ca_bundle_path' => '/fakepath/nocerts',
176
- 'append_builtin_cert' => false
189
+ 'append_builtin_cert' => false,
190
+ 'max_retries' => 15,
191
+ 'retry_max_interval' => 0.5,
192
+ 'retry_initial_interval' => 0.2,
177
193
  })
178
194
  plugin.register
179
195
  allow(plugin.instance_variable_get(:@logger)).to receive(:error)
@@ -194,7 +210,10 @@ describe LogStash::Outputs::Scalyr do
194
210
  'api_write_token' => '1234',
195
211
  'perform_connectivity_check' => false,
196
212
  'ssl_ca_bundle_path' => '/fakepath/nocerts',
197
- 'append_builtin_cert' => false
213
+ 'append_builtin_cert' => false,
214
+ 'max_retries' => 2,
215
+ 'retry_max_interval' => 2,
216
+ 'retry_initial_interval' => 0.2,
198
217
  })
199
218
  plugin.register
200
219
  plugin.instance_variable_set(:@running, false)
@@ -211,7 +230,7 @@ describe LogStash::Outputs::Scalyr do
211
230
  :record_count=>3,
212
231
  :total_batches=>1,
213
232
  :url=>"https://agent.scalyr.com/addEvents",
214
- :will_retry_in_seconds=>2,
233
+ :will_retry_in_seconds=>0.4,
215
234
  :body=>"stubbed response"
216
235
  }
217
236
  )
@@ -227,7 +246,10 @@ describe LogStash::Outputs::Scalyr do
227
246
  'api_write_token' => '1234',
228
247
  'perform_connectivity_check' => false,
229
248
  'ssl_ca_bundle_path' => '/fakepath/nocerts',
230
- 'append_builtin_cert' => false
249
+ 'append_builtin_cert' => false,
250
+ 'max_retries' => 2,
251
+ 'retry_max_interval' => 2,
252
+ 'retry_initial_interval' => 0.2,
231
253
  })
232
254
  plugin.register
233
255
  plugin.instance_variable_set(:@running, false)
@@ -244,7 +266,7 @@ describe LogStash::Outputs::Scalyr do
244
266
  :record_count=>3,
245
267
  :total_batches=>1,
246
268
  :url=>"https://agent.scalyr.com/addEvents",
247
- :will_retry_in_seconds=>2,
269
+ :will_retry_in_seconds=>0.4,
248
270
  :body=>"stubbed response"
249
271
  }
250
272
  )
@@ -260,7 +282,10 @@ describe LogStash::Outputs::Scalyr do
260
282
  'api_write_token' => '1234',
261
283
  'perform_connectivity_check' => false,
262
284
  'ssl_ca_bundle_path' => '/fakepath/nocerts',
263
- 'append_builtin_cert' => false
285
+ 'append_builtin_cert' => false,
286
+ 'max_retries' => 2,
287
+ 'retry_max_interval' => 2,
288
+ 'retry_initial_interval' => 0.2,
264
289
  })
265
290
  plugin.register
266
291
  plugin.instance_variable_set(:@running, false)
@@ -277,7 +302,7 @@ describe LogStash::Outputs::Scalyr do
277
302
  :record_count=>3,
278
303
  :total_batches=>1,
279
304
  :url=>"https://agent.scalyr.com/addEvents",
280
- :will_retry_in_seconds=>2,
305
+ :will_retry_in_seconds=>0.4,
281
306
  :body=>("0123456789" * 50) + "012345678..."
282
307
  }
283
308
  )
@@ -294,7 +319,10 @@ describe LogStash::Outputs::Scalyr do
294
319
  'api_write_token' => '1234',
295
320
  'perform_connectivity_check' => false,
296
321
  'ssl_ca_bundle_path' => '/fakepath/nocerts',
297
- 'append_builtin_cert' => false
322
+ 'append_builtin_cert' => false,
323
+ 'max_retries' => 2,
324
+ 'retry_max_interval' => 2,
325
+ 'retry_initial_interval' => 0.2,
298
326
  })
299
327
  plugin.register
300
328
  plugin.instance_variable_set(:@running, false)
@@ -56,6 +56,65 @@ describe LogStash::Outputs::Scalyr do
56
56
  events
57
57
  }
58
58
 
59
+ let(:sample_events_with_severity) {
60
+ events = []
61
+ for i in 0..6 do
62
+ # valid severity - integer
63
+ e = LogStash::Event.new
64
+ e.set('source_host', "my host #{i}")
65
+ e.set('source_file', "my file #{i}")
66
+ e.set('severity', i)
67
+ e.set('seq', i)
68
+ e.set('nested', {'a'=>1, 'b'=>[3,4,5]})
69
+ e.set('tags', ['t1', 't2', 't3'])
70
+ events.push(e)
71
+ end
72
+ for i in 0..6 do
73
+ # valid severity - string
74
+ e = LogStash::Event.new
75
+ e.set('source_host', "my host #{i}")
76
+ e.set('source_file', "my file #{i}")
77
+ e.set('severity', i.to_s)
78
+ e.set('seq', i)
79
+ e.set('nested', {'a'=>1, 'b'=>[3,4,5]})
80
+ e.set('tags', ['t1', 't2', 't3'])
81
+ events.push(e)
82
+ end
83
+
84
+ # invalid severity values
85
+ e = LogStash::Event.new
86
+ e.set('source_host', "my host a")
87
+ e.set('severity', -1)
88
+ events.push(e)
89
+
90
+ e = LogStash::Event.new
91
+ e.set('source_host', "my host a")
92
+ e.set('severity', 7)
93
+ events.push(e)
94
+
95
+ e = LogStash::Event.new
96
+ e.set('source_host', "my host a")
97
+ e.set('severity', "invalid")
98
+ events.push(e)
99
+
100
+ events
101
+ }
102
+
103
+ let(:sample_events_with_level) {
104
+ events = []
105
+ for i in 0..6 do
106
+ e = LogStash::Event.new
107
+ e.set('source_host', "my host #{i}")
108
+ e.set('source_file', "my file #{i}")
109
+ e.set('level', i)
110
+ e.set('seq', i)
111
+ e.set('nested', {'a'=>1, 'b'=>[3,4,5]})
112
+ e.set('tags', ['t1', 't2', 't3'])
113
+ events.push(e)
114
+ end
115
+ events
116
+ }
117
+
59
118
  describe "#build_multi_event_request_array" do
60
119
 
61
120
  context "test get_stats and send_status" do
@@ -225,6 +284,117 @@ describe LogStash::Outputs::Scalyr do
225
284
  end
226
285
  end
227
286
 
287
+ context "when severity field is configured" do
288
+ it "works correctly when severity event attribute is specified" do
289
+ plugin = LogStash::Outputs::Scalyr.new({
290
+ 'api_write_token' => '1234',
291
+ 'perform_connectivity_check' => false,
292
+ 'severity_field' => 'severity',
293
+ })
294
+ allow(plugin).to receive(:send_status).and_return(nil)
295
+ plugin.register
296
+ result = plugin.build_multi_event_request_array(sample_events_with_severity)
297
+ body = JSON.parse(result[0][:body])
298
+ expect(body['events'].size).to eq(7 + 7 + 3)
299
+
300
+ (0..6).each do |index|
301
+ expect(body['events'][index]['attrs'].fetch('severity', nil)).to eq(nil)
302
+ expect(body['events'][index]['attrs'].fetch('sev', nil)).to eq(nil)
303
+ expect(body['events'][index]['sev']).to eq(index)
304
+ end
305
+
306
+ (7..13).each do |index|
307
+ expect(body['events'][index]['attrs'].fetch('severity', nil)).to eq(nil)
308
+ expect(body['events'][index]['attrs'].fetch('sev', nil)).to eq(nil)
309
+ expect(body['events'][index]['sev']).to eq(index - 7)
310
+ end
311
+
312
+ expect(body['events'][14]['attrs'].fetch('severity', nil)).to eq(-1)
313
+ expect(body['events'][14].key?("sev")).to eq(false)
314
+ expect(body['events'][14]['sev']).to eq(nil)
315
+ expect(body['events'][15]['attrs'].fetch('severity', nil)).to eq(7)
316
+ expect(body['events'][15].key?("sev")).to eq(false)
317
+ expect(body['events'][15]['sev']).to eq(nil)
318
+ expect(body['events'][16]['attrs'].fetch('severity', nil)).to eq("invalid")
319
+ expect(body['events'][16].key?("sev")).to eq(false)
320
+ expect(body['events'][16]['sev']).to eq(nil)
321
+ end
322
+
323
+ it "works correctly when level event attribute is specified" do
324
+ plugin = LogStash::Outputs::Scalyr.new({
325
+ 'api_write_token' => '1234',
326
+ 'perform_connectivity_check' => false,
327
+ 'severity_field' => 'level',
328
+ })
329
+ allow(plugin).to receive(:send_status).and_return(nil)
330
+ plugin.register
331
+ result = plugin.build_multi_event_request_array(sample_events_with_level)
332
+ body = JSON.parse(result[0][:body])
333
+ expect(body['events'].size).to eq(7)
334
+
335
+ (0..6).each do |index|
336
+ expect(body['events'][index]['attrs'].fetch('level', nil)).to eq(nil)
337
+ expect(body['events'][index]['attrs'].fetch('severity', nil)).to eq(nil)
338
+ expect(body['events'][index]['attrs'].fetch('sev', nil)).to eq(nil)
339
+ expect(body['events'][index]['sev']).to eq(index)
340
+ end
341
+ end
342
+
343
+ it "works correctly when severity event attribute is not specified" do
344
+ plugin = LogStash::Outputs::Scalyr.new({
345
+ 'api_write_token' => '1234',
346
+ 'perform_connectivity_check' => false,
347
+ 'severity_field' => 'severity',
348
+ })
349
+ allow(plugin).to receive(:send_status).and_return(nil)
350
+ plugin.register
351
+ result = plugin.build_multi_event_request_array(sample_events)
352
+ body = JSON.parse(result[0][:body])
353
+ expect(body['events'].size).to eq(3)
354
+
355
+ (0..2).each do |index|
356
+ expect(body['events'][index]['attrs'].fetch('severity', nil)).to eq(nil)
357
+ expect(body['events'][index]['attrs'].fetch('sev', nil)).to eq(nil)
358
+ expect(body['events'][index]['sev']).to eq(nil)
359
+ end
360
+ end
361
+
362
+ it "works correctly when severity event attribute is not specified but severity field is not set" do
363
+ # Since severity_field config option is not set, severity field should be treated as a
364
+ # regular event attribute and not as s a special top level Event.sev field
365
+ plugin = LogStash::Outputs::Scalyr.new({
366
+ 'api_write_token' => '1234',
367
+ 'perform_connectivity_check' => false,
368
+ 'severity_field' => nil,
369
+ })
370
+ allow(plugin).to receive(:send_status).and_return(nil)
371
+ plugin.register
372
+ result = plugin.build_multi_event_request_array(sample_events_with_severity)
373
+ body = JSON.parse(result[0][:body])
374
+ expect(body['events'].size).to eq(7 + 7 + 3)
375
+
376
+ (0..6).each do |index|
377
+ expect(body['events'][index]['attrs'].fetch('severity', nil)).to eq(index)
378
+ expect(body['events'][index]['sev']).to eq(nil)
379
+ end
380
+
381
+ (7..13).each do |index|
382
+ expect(body['events'][index]['attrs'].fetch('severity', nil)).to eq((index - 7).to_s)
383
+ expect(body['events'][index]['sev']).to eq(nil)
384
+ end
385
+
386
+ expect(body['events'][14]['attrs'].fetch('severity', nil)).to eq(-1)
387
+ expect(body['events'][14].key?("sev")).to eq(false)
388
+ expect(body['events'][14]['sev']).to eq(nil)
389
+ expect(body['events'][15]['attrs'].fetch('severity', nil)).to eq(7)
390
+ expect(body['events'][15].key?("sev")).to eq(false)
391
+ expect(body['events'][15]['sev']).to eq(nil)
392
+ expect(body['events'][16]['attrs'].fetch('severity', nil)).to eq("invalid")
393
+ expect(body['events'][16].key?("sev")).to eq(false)
394
+ expect(body['events'][16]['sev']).to eq(nil)
395
+ end
396
+ end
397
+
228
398
  context "when serverhost_field is missing" do
229
399
  it "does not contain log file" do
230
400
  plugin = LogStash::Outputs::Scalyr.new({'api_write_token' => '1234', 'perform_connectivity_check' => false})
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-output-scalyr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4.beta
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edward Chee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-21 00:00:00.000000000 Z
11
+ date: 2022-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -156,6 +156,11 @@ files:
156
156
  - NOTICE.TXT
157
157
  - README.md
158
158
  - lib/logstash/outputs/scalyr.rb
159
+ - lib/scalyr/certs/aaa_cert_services_ca_root.pem
160
+ - lib/scalyr/certs/ca_certs.crt
161
+ - lib/scalyr/certs/letsencrypt_isrg_root_x1_selfsigned_root.pem
162
+ - lib/scalyr/certs/letsencrypt_isrg_root_x2_selfsigned_root.pem
163
+ - lib/scalyr/certs/scalyr_agent_ca_root.pem
159
164
  - lib/scalyr/common/client.rb
160
165
  - lib/scalyr/common/util.rb
161
166
  - lib/scalyr/constants.rb
@@ -186,9 +191,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
186
191
  version: '0'
187
192
  required_rubygems_version: !ruby/object:Gem::Requirement
188
193
  requirements:
189
- - - ">"
194
+ - - ">="
190
195
  - !ruby/object:Gem::Version
191
- version: 1.3.1
196
+ version: '0'
192
197
  requirements: []
193
198
  rubyforge_project:
194
199
  rubygems_version: 2.7.10