logstash-output-stackdriver_logging 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7eeee7c50713fc116155c686aec51663bb78b62b7ec3015ab65abb2847a86d8a
4
+ data.tar.gz: e8ae42e6139cf1c71a70ecc6aa3efc47888e29c6614548823ff55c4dd259513c
5
+ SHA512:
6
+ metadata.gz: f1f503d74a900679df982128b5b013355e4f7b9315001edc1a0d0fae808e9086fc7812010037e2eea468c089af704fd96beda645e25641486ccaa6319f8f8eae
7
+ data.tar.gz: 2f2df41576e922909ccef24c32b0c7d1d02a2282cb5325454c09d18e402af9d6598b953c5d8475a98859a17bd3b36d04e421566e230203c4ec3afdb97c98fd57
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ ## 2.0.3
2
+ - Docs: Set the default_codec doc attribute.
3
+
4
+ ## 2.0.2
5
+ - Docs: Add documentation template
6
+ ## 2.0.1
7
+ - Add encoding: utf-8 to spec files. This can help prevent issues during testing.
8
+ ## 2.0.0
9
+ - Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
10
+ instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
11
+ - Dependency on logstash-core update to 2.0
12
+
data/CONTRIBUTORS ADDED
@@ -0,0 +1,11 @@
1
+ The following is a list of people who have contributed ideas, code, bug
2
+ reports, or in general have helped logstash along its way.
3
+
4
+ Contributors:
5
+ * Aaron Mildenstein (untergeek)
6
+ * Pier-Hugues Pellerin (ph)
7
+
8
+ Note: If you've sent us patches, bug reports, or otherwise contributed to
9
+ Logstash, and you aren't on the list above and want to be, please let us know
10
+ and we'll make sure you're here. Contributions from folks like you are what make
11
+ open source awesome.
data/DEVELOPER.md ADDED
@@ -0,0 +1,2 @@
1
+ # logstash-output-example
2
+ Example output plugin. This should help bootstrap your effort to write your own output plugin!
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'logstash-core'
6
+ gem 'logstash-core-plugin-api'
7
+ gem 'google-api-client'
8
+ gem 'googleauth'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Geoff Garbers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/NOTICE.TXT ADDED
@@ -0,0 +1,5 @@
1
+ Elasticsearch
2
+ Copyright 2012-2015 Elasticsearch
3
+
4
+ This product includes software developed by The Apache Software
5
+ Foundation (http://www.apache.org/).
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # Stackdriver Logging Logstash Plugin
2
+
3
+ This is a plugin for [Logstash](https://github.com/elastic/logstash).
4
+
5
+ It is fully free and fully open source. The license is MIT, meaning you are pretty much free to use it however you want in whatever way.
6
+
7
+
8
+ ## Summary
9
+
10
+ This plugin sends events to Stackdriver Logging. Events are sent in batches as they are received.
11
+
12
+
13
+ ## Usage
14
+
15
+ This is an example of Logstash config for this plugin:
16
+
17
+ ```
18
+ output {
19
+ stackdriver_logging {
20
+ project_id => "folkloric-guru-278" (optional) <1>
21
+ key_file => "/path/to/key_file.json" (optional) <2>
22
+ log_name => "" (required) <3>
23
+ severity_field => "severity" (optional)
24
+ timestamp_field => "@timestamp" (optional)
25
+ default_severity => "default" (optional)
26
+ strip_at_fields => false (optional)
27
+ strip_fields => [] (optional)
28
+ }
29
+ }
30
+ ```
31
+
32
+ There are some points to keep in mind when providing configuration:
33
+
34
+ 1. When running on Google Compute Engine and no `project_id` is provided, the `project_id` paramater will be
35
+ automatically retrieved from the metadata server.
36
+
37
+ 2. If no key is provided, defaults to using [Application Default Credentials](https://cloud.google.com/docs/authentication/production).
38
+
39
+ 3. The log name can be interpolated with event fields, to extract the log name from a message (ie: `log_name => "%{[log_name]}"`).
40
+
41
+ ## Considerations
42
+
43
+ There is a cost to storing log data in Stackdriver Logging. See [the pricing guide](https://cloud.google.com/stackdriver/pricing)
44
+ for more information on costs involved.
45
+
46
+ All logs are stored under the `global` resource.
@@ -0,0 +1,177 @@
1
+ # encoding: utf-8
2
+ require "logstash/outputs/base"
3
+ require "logstash/namespace"
4
+ require "logstash/logging"
5
+ require 'google/apis/logging_v2'
6
+ require 'googleauth'
7
+ require 'json'
8
+ require 'faraday'
9
+
10
+ # === Summary
11
+ #
12
+ # This plugin sends events to Stackdriver Logging. Events are sent in batches as they are received.
13
+ #
14
+ # === Environment configuration
15
+ #
16
+ # Logging should already be configured on your Google Cloud Platform project. However, you will need
17
+ # to create a service account with permissions to write logs.
18
+ #
19
+ # === Usage
20
+ #
21
+ # This is an example of Logstash config for this plugin:
22
+ #
23
+ # [source,ruby]
24
+ # --------------------------
25
+ # output {
26
+ # stackdriver_logging {
27
+ # project_id => "folkloric-guru-278" (optional) <1>
28
+ # key_file => "/path/to/key_file.json" (optional) <2>
29
+ # log_name => "" (required) <3>
30
+ # severity_field => "severity" (optional)
31
+ # timestamp_field => "@timestamp" (optional)
32
+ # default_severity => "default" (optional)
33
+ # strip_at_fields => false (optional)
34
+ # strip_fields => [] (optional)
35
+ # }
36
+ # }
37
+ # --------------------------
38
+ #
39
+ # <1> If running on Google Compute Engine, the project ID will be automatically retrieved from the metadata server. Required
40
+ # if not running within GCE.
41
+ #
42
+ # <2> If no key is provided, defaults to using https://cloud.google.com/docs/authentication/production[Application Default Credentials].
43
+ #
44
+ # <3> The log name can be interpolated with log data, to extract the log name from a message.
45
+ #
46
+ # === Considerations
47
+ #
48
+ # There is a cost to storing log data in Stackdriver Logging. See https://cloud.google.com/stackdriver/pricing[the pricing guide]
49
+ # for more information on costs involved.
50
+ #
51
+ # All logs are stored under the `global` resource.
52
+ #
53
+ #
54
+ class LogStash::Outputs::StackdriverLogging < LogStash::Outputs::Base
55
+ config_name "stackdriver_logging"
56
+
57
+ # The Google Cloud project to write the logs to. This is optional if running on GCE,
58
+ # and will default to the instance's project.
59
+ config :project_id, :validate => :string, :required => false, :default => nil
60
+
61
+ # The path to the service account JSON file that contains the credentials
62
+ # of the service account to write logs as.
63
+ config :key_file, :validate => :path, :required => false
64
+
65
+ # The name of the log to write logs to. Can be interpolated with event fields.
66
+ config :log_name, :validate => :string, :required => true
67
+
68
+ # The name of the field that contains the logging severity level. If no field with this name is specified, defaults
69
+ # to @default_severity.
70
+ config :severity_field, :validate => :string, :required => false, :default => "severity"
71
+
72
+ # The field name in the event that contains the timestamp of the log message.
73
+ config :timestamp_field, :validate => :string, :required => false, :default => "@timestamp"
74
+
75
+ # If no severity is found, the default severity level to assume.
76
+ config :default_severity, :validate => :string, :required => false, :default => "default"
77
+
78
+ # Boolean flag indicating whether or not to remove the fields in the event that are prefixed with "@", immediately
79
+ # prior to sending.
80
+ config :strip_at_fields, :validate => :boolean, :required => false, :default => false
81
+
82
+ # Array of field names to remove from the event immediately prior to sending.
83
+ config :strip_fields, :validate => :array, :required => false, :default => []
84
+
85
+ concurrency :single
86
+
87
+ public
88
+ def register
89
+ @service = Google::Apis::LoggingV2::LoggingService.new
90
+ scope = %w(https://www.googleapis.com/auth/logging.write)
91
+
92
+ # Always load key file if provided.
93
+ if @key_file
94
+ @service.authorization = Google::Auth::ServiceAccountCredentials.make_creds(json_key_io: File.open(@key_file),
95
+ scope: scope)
96
+ # Fall back to getting the application default credentials.
97
+ else
98
+ @service.authorization = Google::Auth.get_application_default(scope)
99
+ end
100
+
101
+ # project_id is not defined. Try to extract it from teh metadata server.
102
+ unless @project_id
103
+ if Google::Auth::GCECredentials.on_gce?
104
+ connection = Faraday::Connection.new("http://169.254.169.254/computeMetadata/v1/", { :headers => headers })
105
+ connection.headers = { "Metadata-Flavor": "Google" }
106
+ response = connection.get "project/project-id"
107
+
108
+ if response.status
109
+ @project_id = response.body.to_s.strip
110
+ end
111
+
112
+
113
+ else
114
+ @logger.error "Unable to detect the Google Cloud project ID to which logs should be written." \
115
+ "Please ensure that you specify the `project_id` config parameter if not running on the Google " \
116
+ "Cloud Platform."
117
+ @logger.error "You will not be able to be able to write logs to Google Cloud until this is resolved."
118
+ end
119
+ end
120
+ end
121
+
122
+ public
123
+ # @param [Array] events
124
+ def multi_receive(events)
125
+ # Do nothing if no events are received.
126
+ if events.length < 1
127
+ return
128
+ end
129
+
130
+ entries = []
131
+
132
+ events.each do |event|
133
+ entry = Google::Apis::LoggingV2::LogEntry.new
134
+ entry.severity = event.include?(@severity_field) ? event.get(@severity_field) : @default_severity
135
+ entry.log_name = "projects/%{project}/logs/%{log_name}" % { :project => @project_id, :log_name => event.sprintf(@log_name) }
136
+ entry.timestamp = event.get(@timestamp_field)
137
+ entry.json_payload = event.to_hash
138
+
139
+ # Strip the "@" fields.
140
+ if @strip_at_fields or @strip_fields.length > 0
141
+ filtered = {}
142
+
143
+ entry.json_payload.each do |key, value|
144
+ if @strip_at_fields && key[0] == "@"
145
+ next
146
+ end
147
+
148
+ if @strip_fields.length > 0 && @strip_fields.include?(key)
149
+ next
150
+ end
151
+
152
+ filtered[key] = value
153
+ end
154
+
155
+ entry.json_payload = filtered
156
+ end
157
+
158
+ entries.push entry
159
+ end
160
+
161
+ resource = Google::Apis::LoggingV2::MonitoredResource.new
162
+ resource.type = "global"
163
+ resource.labels = { :project_id => @project_id }
164
+
165
+ request = Google::Apis::LoggingV2::WriteLogEntriesRequest.new(entries: entries)
166
+ request.resource = resource
167
+
168
+ @service.write_entry_log_entries(request) do |result, error|
169
+ if error
170
+ @logger.error "Unable to write log entries to Stackdriver Logging."
171
+ @logger.error "Received this error: " + error.to_s
172
+ else
173
+ @logger.debug("Wrote %{length} entries successfully." % { :length => entries.length })
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,27 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'logstash-output-stackdriver_logging'
3
+ s.version = '0.1.0'
4
+ s.licenses = ['MIT']
5
+ s.summary = "Writes payloads to Stackdriver Logging."
6
+ s.description = ""
7
+ s.authors = ["Geoff Garbers"]
8
+ s.email = "geoff@garbers.co.za"
9
+ s.homepage = "https://github.com/garbetjie/logstash-output-stackdriver"
10
+ s.require_paths = %w(lib generated)
11
+
12
+ # Files
13
+ s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
14
+ # Tests
15
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
16
+
17
+ # Special flag to let us know this is actually a logstash plugin
18
+ s.metadata = { "logstash_plugin" => "true", "logstash_group" => "output" }
19
+
20
+ # Gem dependencies
21
+ #
22
+ s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
23
+ s.add_runtime_dependency "logstash-codec-plain"
24
+ s.add_runtime_dependency "google-api-client"
25
+ s.add_runtime_dependency "googleauth"
26
+ s.add_development_dependency 'logstash-devutils'
27
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/stackdriver_logging"
4
+ require "logstash/codecs/plain"
5
+ require "logstash/event"
6
+
7
+ describe LogStash::Outputs::StackdriverLogging do
8
+ let(:sample_event) { LogStash::Event.new }
9
+ let(:output) { LogStash::Outputs::StackdriverLogging.new }
10
+
11
+ before do
12
+ output.register
13
+ end
14
+
15
+ describe "receive message" do
16
+ subject { output.receive(sample_event) }
17
+
18
+ it "returns a string" do
19
+ expect(subject).to eq("Event received")
20
+ end
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-output-stackdriver_logging
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Geoff Garbers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-11-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '1.60'
19
+ - - "<="
20
+ - !ruby/object:Gem::Version
21
+ version: '2.99'
22
+ name: logstash-core-plugin-api
23
+ prerelease: false
24
+ type: :runtime
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '1.60'
30
+ - - "<="
31
+ - !ruby/object:Gem::Version
32
+ version: '2.99'
33
+ - !ruby/object:Gem::Dependency
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ name: logstash-codec-plain
40
+ prerelease: false
41
+ type: :runtime
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ name: google-api-client
54
+ prerelease: false
55
+ type: :runtime
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ name: googleauth
68
+ prerelease: false
69
+ type: :runtime
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ name: logstash-devutils
82
+ prerelease: false
83
+ type: :development
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ description: ''
90
+ email: geoff@garbers.co.za
91
+ executables: []
92
+ extensions: []
93
+ extra_rdoc_files: []
94
+ files:
95
+ - CHANGELOG.md
96
+ - CONTRIBUTORS
97
+ - DEVELOPER.md
98
+ - Gemfile
99
+ - LICENSE
100
+ - NOTICE.TXT
101
+ - README.md
102
+ - lib/logstash/outputs/stackdriver_logging.rb
103
+ - logstash-output-stackdriver_logging.gemspec
104
+ - spec/outputs/stackdriver_logging_spec.rb
105
+ homepage: https://github.com/garbetjie/logstash-output-stackdriver
106
+ licenses:
107
+ - MIT
108
+ metadata:
109
+ logstash_plugin: 'true'
110
+ logstash_group: output
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ - generated
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.6.13
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Writes payloads to Stackdriver Logging.
132
+ test_files:
133
+ - spec/outputs/stackdriver_logging_spec.rb