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 +7 -0
- data/CHANGELOG.md +12 -0
- data/CONTRIBUTORS +11 -0
- data/DEVELOPER.md +2 -0
- data/Gemfile +8 -0
- data/LICENSE +21 -0
- data/NOTICE.TXT +5 -0
- data/README.md +46 -0
- data/lib/logstash/outputs/stackdriver_logging.rb +177 -0
- data/logstash-output-stackdriver_logging.gemspec +27 -0
- data/spec/outputs/stackdriver_logging_spec.rb +22 -0
- metadata +133 -0
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
data/Gemfile
ADDED
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
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
|