fluent-plugin-oci-logging 1.0.2
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/README.md +136 -0
- data/lib/fluent/plugin/logging_setup.rb +286 -0
- data/lib/fluent/plugin/logging_utils.rb +207 -0
- data/lib/fluent/plugin/os.rb +48 -0
- data/lib/fluent/plugin/out_oci_logging.rb +92 -0
- data/lib/version.rb +22 -0
- metadata +193 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ff4390e3b3e77082712da61a486e9bf756a55e849053490e03eb884a260e0d5b
|
4
|
+
data.tar.gz: 2e232b1bf8c667db6d4d2a96d9746b1a71a26d056e126a8b79eda83e3abaf5ed
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 382946fb56ed0575bc5e7996c96f92abec7c59efaee23fba3a2e76077d280ed6ff22f555732e27ca6959f19f26a6961bf0298277da02d775ac5d48f8623ddc09
|
7
|
+
data.tar.gz: 985ec4b0de8339aa19a33e03d6c67399137ca16f248657bc7b8216867f6e4c12577f9b1e9bd2d8114b7fe948f78fa860fe6b48ac342e42b773cc344407a633af
|
data/README.md
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
# Oracle Cloud Infrastructure Fluentd Plugin
|
2
|
+
|
3
|
+
This is the official [fluentd](https://docs.fluentd.org/) plugin for the Oracle
|
4
|
+
Cloud Infrastructure (OCI) Logging service. This project is open source, in
|
5
|
+
active development and maintained by Oracle.
|
6
|
+
|
7
|
+
## Requirements
|
8
|
+
To use this fluentd plugin, you must have:
|
9
|
+
|
10
|
+
* An Oracle Cloud Infrastructure acount.
|
11
|
+
* A user created in that account, in a group with a policy that grants the
|
12
|
+
desired permissions. This can be a user for yourself, or another person/system
|
13
|
+
that needs to call the API. For an example of how to set up a new user, group,
|
14
|
+
compartment, and policy, see [Adding Users](https://docs.cloud.oracle.com/Content/GSG/Tasks/addingusers.htm)
|
15
|
+
in the Getting Started Guide. For a list of typical policies you may want to
|
16
|
+
use, see [Common Policies](https://docs.cloud.oracle.com/Content/Identity/Concepts/commonpolicies.htm)
|
17
|
+
in the User Guide.
|
18
|
+
* Ruby version 2.2 or later running on Mac, Linux or Windows.
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Add this line to your application's Gemfile:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
gem 'fluent-plugin-oci-logging'
|
26
|
+
```
|
27
|
+
|
28
|
+
And then execute:
|
29
|
+
|
30
|
+
```shell
|
31
|
+
$ bundle
|
32
|
+
```
|
33
|
+
|
34
|
+
Or install it yourself as:
|
35
|
+
|
36
|
+
```
|
37
|
+
gem install fluent-plugin-oci-logging
|
38
|
+
```
|
39
|
+
|
40
|
+
Besides the plugin, the above commands will also automatically install fluentd,
|
41
|
+
as well as the rest of the required ruby dependencies, in your system.
|
42
|
+
|
43
|
+
## Configuration
|
44
|
+
|
45
|
+
For usage with [instance principals](https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/callingservicesfrominstances.htm):
|
46
|
+
|
47
|
+
```xml
|
48
|
+
<source>
|
49
|
+
@type dummy
|
50
|
+
tag test
|
51
|
+
dummy {"test":"message"}
|
52
|
+
</source>
|
53
|
+
<match **>
|
54
|
+
@type oci_logging
|
55
|
+
log_object_id ocid1.log.oc1.XXX.xxx
|
56
|
+
</match>
|
57
|
+
```
|
58
|
+
|
59
|
+
For usage with an [API signing key]( https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm):
|
60
|
+
|
61
|
+
```xml
|
62
|
+
<source>
|
63
|
+
@type dummy
|
64
|
+
tag test
|
65
|
+
dummy {"test":"message"}
|
66
|
+
</source>
|
67
|
+
<match **>
|
68
|
+
@type oci_logging
|
69
|
+
principal_override user
|
70
|
+
log_object_id ocid1.log.oc1.XXX.xxx
|
71
|
+
</match>
|
72
|
+
```
|
73
|
+
|
74
|
+
To authenticate as a particular user, you need to [generate an API Signing Key](https://docs.cloud.oracle.com/en-us/iaas/Content/API/SDKDocs/cliconfigure.htm) for that user.
|
75
|
+
|
76
|
+
## Logging Setup
|
77
|
+
|
78
|
+
Detailed instructions, alongside examples, on how you can setup your logging
|
79
|
+
environment can be found in the official [OCI docs](https://docs.cloud.oracle.com/en-us/iaas/Content/Logging/Task/managinglogs.htm).
|
80
|
+
Also, to find out how to search your logs, you can check the documentation
|
81
|
+
for [log search](https://docs.cloud.oracle.com/en-us/iaas/Content/Logging/Concepts/searchinglogs.htm).
|
82
|
+
|
83
|
+
## Documentation
|
84
|
+
|
85
|
+
Full documentation, including prerequisites, installation, and configuration
|
86
|
+
instructions can be found [here](https://docs.cloud.oracle.com/en-us/iaas/Content/Logging/Concepts/loggingoverview.htm).
|
87
|
+
|
88
|
+
API reference can be found [here](https://docs.cloud.oracle.com/en-us/iaas/tools/ruby/latest/index.html).
|
89
|
+
|
90
|
+
This documentation can be found installed in your system in the gem specific directory. You can find its exact location by running the command:
|
91
|
+
|
92
|
+
```shell
|
93
|
+
gem contents fluent-plugin-oci-logging
|
94
|
+
```
|
95
|
+
|
96
|
+
Alternatively, you can also view it via ruby's documentation tool `ri` with the following command:
|
97
|
+
|
98
|
+
```shell
|
99
|
+
ri -f markdown fluent-plugin-oci-logging:README
|
100
|
+
```
|
101
|
+
|
102
|
+
Finally, you can view it by extracting the gem contents (the gem file itself is a tar archive).
|
103
|
+
|
104
|
+
|
105
|
+
## Known Issues
|
106
|
+
|
107
|
+
You can find information on any known issues with the SDK under the [Issues](https://github.com/oracle/fluent-plugin-oci-logging/issues) tab.
|
108
|
+
|
109
|
+
## Questions or Feedback?
|
110
|
+
|
111
|
+
Please [open an issue for any problems or questions](https://github.com/oracle/fluent-plugin-oci-logging/issues) you may have.
|
112
|
+
|
113
|
+
Addtional ways to get in touch:
|
114
|
+
|
115
|
+
* [Stack Overflow](https://stackoverflow.com/): Please use the [oracle-cloud-infrastructure](https://stackoverflow.com/questions/tagged/oracle-cloud-infrastructure) and [oci-ruby-sdk](https://stackoverflow.com/questions/tagged/oci-ruby-sdk) tags in your post
|
116
|
+
* [Developer Tools section](https://community.oracle.com/community/cloud_computing/bare-metal/content?filterID=contentstatus%5Bpublished%5D~category%5Bdeveloper-tools%5D&filterID=contentstatus%5Bpublished%5D~objecttype~objecttype%5Bthread%5D) of the Oracle Cloud forums
|
117
|
+
* [My Oracle Support](https://support.oracle.com)
|
118
|
+
|
119
|
+
## Contributing
|
120
|
+
|
121
|
+
This project welcomes contributions from the community. Before submitting a pull
|
122
|
+
request, please [review our contribution guide](./CONTRIBUTING.md).
|
123
|
+
|
124
|
+
## Security
|
125
|
+
|
126
|
+
Please consult the [security guide](./SECURITY.md) for our responsible security
|
127
|
+
vulnerability disclosure process.
|
128
|
+
|
129
|
+
## License
|
130
|
+
|
131
|
+
Copyright (c) 2021, Oracle and/or its affiliates.
|
132
|
+
|
133
|
+
This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at <https://oss.oracle.com/licenses/upl>
|
134
|
+
or Apache License 2.0 as shown at <http://www.apache.org/licenses/LICENSE-2.0>. You may choose either license.
|
135
|
+
|
136
|
+
See [LICENSE](./LICENSE.txt) for more details.
|
@@ -0,0 +1,286 @@
|
|
1
|
+
# fluent-plugin-oci-logging version 1.0.
|
2
|
+
#
|
3
|
+
# Copyright (c) 2021, Oracle and/or its affiliates.
|
4
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
require 'retriable'
|
9
|
+
require 'oci'
|
10
|
+
|
11
|
+
require_relative 'os'
|
12
|
+
require_relative 'logging_utils'
|
13
|
+
|
14
|
+
module Fluent
|
15
|
+
module Plugin
|
16
|
+
# Setup code for OCI Logging
|
17
|
+
module PublicLoggingSetup
|
18
|
+
RETRIES = 3
|
19
|
+
USER_SIGNER_TYPE = 'user'
|
20
|
+
AUTO_SIGNER_TYPE = 'auto'
|
21
|
+
LINUX_OCI_CONFIG_DIR = Fluent::Plugin::PublicLoggingUtils.determine_linux_config_path
|
22
|
+
WINDOWS_OCI_CONFIG_DIR = Fluent::Plugin::PublicLoggingUtils.determine_windows_config_path
|
23
|
+
USER_CONFIG_PROFILE_NAME = Fluent::Plugin::PublicLoggingUtils.determine_config_profile_name(LINUX_OCI_CONFIG_DIR, WINDOWS_OCI_CONFIG_DIR)
|
24
|
+
PUBLIC_RESOURCE_PRINCIPAL_ENV_FILE = '/etc/resource_principal_env'
|
25
|
+
|
26
|
+
R1_CA_PATH = '/etc/pki/tls/certs/ca-bundle.crt'
|
27
|
+
PUBLIC_DEFAULT_LINUX_CA_PATH = '/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem'
|
28
|
+
PUBLIC_DEFAULT_WINDOWS_CA_PATH = 'C:\\oracle_unified_agent\\unified-monitoring-agent\\embedded\\ssl\\certs\\cacert.pem'
|
29
|
+
PUBLIC_DEFAULT_UBUNTU_CA_PATH = '/etc/ssl/certs/ca-certificates.crt'
|
30
|
+
|
31
|
+
def logger
|
32
|
+
@log ||= OS.windows? ? Logger.new(WINDOWS_UPLOADER_OUTPUT_LOG) : Logger.new($stdout)
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Calculate federation endpoints based on metadata and optional inputs
|
37
|
+
#
|
38
|
+
# @param [String] region the region identifier
|
39
|
+
#
|
40
|
+
# @return [String] the federation endpoint that will be used
|
41
|
+
def get_federation_endpoint(region)
|
42
|
+
if region == 'r1'
|
43
|
+
endpoint = ENV['FEDERATION_ENDPOINT'] || 'https://auth.r1.oracleiaas.com/v1/x509'
|
44
|
+
else
|
45
|
+
if @realmDomainComponent.nil?
|
46
|
+
logger.warn('realm domain is null, fall back to OCI Regions')
|
47
|
+
@realmDomainComponent = OCI::Regions.get_second_level_domain(region) if @realmDomainComponent.nil?
|
48
|
+
end
|
49
|
+
|
50
|
+
endpoint = ENV['FEDERATION_ENDPOINT'] || "https://auth.#{region}.#{@realmDomainComponent}/v1/x509"
|
51
|
+
end
|
52
|
+
|
53
|
+
logger.info("endpoint is #{endpoint} in region #{region}")
|
54
|
+
endpoint
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_instance_md_with_retry(retries = RETRIES)
|
58
|
+
Retriable.retriable(tries: retries, on: StandardError, timeout: 12) do
|
59
|
+
return get_instance_md
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_instance_md
|
64
|
+
# v2 of IMDS requires an authorization header
|
65
|
+
md = get_instance_md_with_url('http://169.254.169.254/opc/v2/instance/')
|
66
|
+
if md.nil?
|
67
|
+
logger.info('IMDS v2 is not available, use v1')
|
68
|
+
md = get_instance_md_with_url('http://169.254.169.254/opc/v1/instance/')
|
69
|
+
end
|
70
|
+
|
71
|
+
if !md.nil?
|
72
|
+
logger.info "Successfully fetch instance metadata for hosts in overlay #{md}"
|
73
|
+
return md
|
74
|
+
else
|
75
|
+
raise StandardError, 'Failure fetching instance metadata, possible '\
|
76
|
+
'reason is network issue or host is not OCI instance'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def get_instance_md_with_url(uri_link)
|
81
|
+
uri = URI.parse(uri_link)
|
82
|
+
http = ::Net::HTTP.new(uri.host, uri.port)
|
83
|
+
http.open_timeout = 2 # in seconds
|
84
|
+
http.read_timeout = 2 # in seconds
|
85
|
+
request = ::Net::HTTP::Get.new(uri.request_uri)
|
86
|
+
request.add_field('Authorization', 'Bearer Oracle') if uri_link.include?('v2')
|
87
|
+
resp = http.request(request)
|
88
|
+
JSON.parse(resp.body)
|
89
|
+
rescue StandardError
|
90
|
+
logger.warn("failed to get instance metadata with link #{uri_link}")
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Calculate logging endpoint from environment or metadata.
|
96
|
+
# Preference is given to the environment variable 'LOGGING_FRONTEND'.
|
97
|
+
#
|
98
|
+
# @param [String] region the region identifier
|
99
|
+
#
|
100
|
+
# @return [String] The logging endpoint that will be used.
|
101
|
+
def get_logging_endpoint(region, logging_endpoint_override: nil)
|
102
|
+
unless logging_endpoint_override.nil?
|
103
|
+
logger.info "using logging endpoint override #{logging_endpoint_override} for testing"
|
104
|
+
return logging_endpoint_override
|
105
|
+
end
|
106
|
+
|
107
|
+
if region == 'r1'
|
108
|
+
endpoint = ENV['LOGGING_FRONTEND'] || "https://ingestion.logging.#{region}.oci.oracleiaas.com"
|
109
|
+
else
|
110
|
+
if @realmDomainComponent.nil?
|
111
|
+
logger.warn('realm domain is null, fall back to OCI Regions')
|
112
|
+
@realmDomainComponent = OCI::Regions.get_second_level_domain(region) if @realmDomainComponent.nil?
|
113
|
+
end
|
114
|
+
|
115
|
+
endpoint = ENV['LOGGING_FRONTEND'] || "https://ingestion.logging.#{region}.oci.#{@realmDomainComponent}"
|
116
|
+
end
|
117
|
+
|
118
|
+
logger.info("endpoint is #{endpoint} in region #{region}")
|
119
|
+
endpoint
|
120
|
+
end
|
121
|
+
|
122
|
+
def get_signer_type(principal_override: nil, config_dir: nil)
|
123
|
+
config_dir ||= OS.windows? ? WINDOWS_OCI_CONFIG_DIR : LINUX_OCI_CONFIG_DIR
|
124
|
+
|
125
|
+
if (File.file?(config_dir) && principal_override != AUTO_SIGNER_TYPE) || principal_override == USER_SIGNER_TYPE
|
126
|
+
begin
|
127
|
+
logger.info("using #{USER_SIGNER_TYPE} signer type with config dir #{config_dir}")
|
128
|
+
oci_config = OCI::ConfigFileLoader.load_config(
|
129
|
+
config_file_location: config_dir, profile_name: USER_CONFIG_PROFILE_NAME
|
130
|
+
)
|
131
|
+
signer_type = USER_SIGNER_TYPE
|
132
|
+
rescue StandardError => e
|
133
|
+
if e.full_message.include?('Profile not found in the given config file.')
|
134
|
+
logger.warn("Profile #{USER_CONFIG_PROFILE_NAME} not configured "\
|
135
|
+
"in user api-key cli using other principal instead: #{e}")
|
136
|
+
signer_type = AUTO_SIGNER_TYPE
|
137
|
+
oci_config = OCI::Config.new
|
138
|
+
else
|
139
|
+
raise "User api-keys not setup correctly: #{e}"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
else # if user api-keys is not setup in the expected format we expect instance principal
|
143
|
+
logger.info("using #{AUTO_SIGNER_TYPE} signer type")
|
144
|
+
signer_type = AUTO_SIGNER_TYPE
|
145
|
+
oci_config = OCI::Config.new
|
146
|
+
end
|
147
|
+
[oci_config, signer_type]
|
148
|
+
end
|
149
|
+
|
150
|
+
##
|
151
|
+
# Configure the signer for the logging client call
|
152
|
+
#
|
153
|
+
# @param [String] signer_type the type of signer that should be returned
|
154
|
+
#
|
155
|
+
# @return [OCI::Signer] a signer that is representative of the signer type
|
156
|
+
def get_signer(oci_config, signer_type)
|
157
|
+
case signer_type
|
158
|
+
when USER_SIGNER_TYPE
|
159
|
+
get_host_info_for_non_oci_instance(oci_config)
|
160
|
+
set_default_ca_file
|
161
|
+
OCI::Signer.new(
|
162
|
+
oci_config.user,
|
163
|
+
oci_config.fingerprint,
|
164
|
+
oci_config.tenancy,
|
165
|
+
oci_config.key_file,
|
166
|
+
pass_phrase: oci_config.pass_phrase
|
167
|
+
)
|
168
|
+
when AUTO_SIGNER_TYPE
|
169
|
+
logger.info 'signer type is "auto", creating signer based on system setup'
|
170
|
+
get_host_info_for_oci_instance
|
171
|
+
set_default_ca_file
|
172
|
+
signer = create_resource_principal_signer
|
173
|
+
if signer.nil?
|
174
|
+
logger.info('resource principal is not setup, use instance principal instead')
|
175
|
+
signer = create_instance_principal_signer
|
176
|
+
else
|
177
|
+
logger.info('use resource principal')
|
178
|
+
end
|
179
|
+
|
180
|
+
signer
|
181
|
+
else
|
182
|
+
raise StandardError, "Principal type #{signer_type} not supported, "\
|
183
|
+
"use 'instance', 'resource' or 'user' instead"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def get_host_info_for_non_oci_instance(oci_config)
|
188
|
+
# set needed properties
|
189
|
+
@region = oci_config.region
|
190
|
+
# for non-OCI instances we can't get the display_name or hostname from IMDS and the fallback is the ip address
|
191
|
+
# of the machine
|
192
|
+
begin
|
193
|
+
@hostname = Socket.gethostname
|
194
|
+
rescue StandardError
|
195
|
+
ip = Socket.ip_address_list.detect { |intf| intf.ipv4_private? }
|
196
|
+
@hostname = ip ? ip.ip_address : 'UNKNOWN'
|
197
|
+
end
|
198
|
+
|
199
|
+
# No metadata service support for non-OCI instances
|
200
|
+
@realmDomainComponent = OCI::Regions.get_second_level_domain(@region)
|
201
|
+
|
202
|
+
logger.info("in non oci instance, region is #{@region}, "\
|
203
|
+
" hostname is #{@hostname}, realm is #{@realmDomainComponent}")
|
204
|
+
end
|
205
|
+
|
206
|
+
def get_host_info_for_oci_instance
|
207
|
+
md = @metadata_override || get_instance_md_with_retry
|
208
|
+
|
209
|
+
@region = md['canonicalRegionName'] == 'us-seattle-1' ? 'r1' : md['canonicalRegionName']
|
210
|
+
@hostname = md.key?('displayName') ? md['displayName'] : ''
|
211
|
+
@realmDomainComponent = md.fetch('regionInfo', {}).fetch(
|
212
|
+
'realmDomainComponent', OCI::Regions.get_second_level_domain(@region)
|
213
|
+
)
|
214
|
+
logger.info("in oci instance, region is #{@region}, hostname is"\
|
215
|
+
" #{@hostname}, realm is #{@realmDomainComponent}")
|
216
|
+
end
|
217
|
+
|
218
|
+
##
|
219
|
+
# Since r1 overlay has a different default make sure to update this
|
220
|
+
#
|
221
|
+
def set_default_ca_file
|
222
|
+
if OS.windows?
|
223
|
+
@ca_file = @ca_file == PUBLIC_DEFAULT_LINUX_CA_PATH ? PUBLIC_DEFAULT_WINDOWS_CA_PATH : @ca_file
|
224
|
+
elsif OS.ubuntu?
|
225
|
+
@ca_file = @ca_file == PUBLIC_DEFAULT_LINUX_CA_PATH ? PUBLIC_DEFAULT_UBUNTU_CA_PATH : @ca_file
|
226
|
+
else
|
227
|
+
@ca_file = @region == 'r1' && @ca_file == PUBLIC_DEFAULT_LINUX_CA_PATH ? R1_CA_PATH : @ca_file
|
228
|
+
end
|
229
|
+
|
230
|
+
if @ca_file.nil?
|
231
|
+
msg = 'ca_file is not specified'
|
232
|
+
logger.error msg
|
233
|
+
raise StandardError, msg
|
234
|
+
end
|
235
|
+
|
236
|
+
# verify the ssl bundle actually exists
|
237
|
+
unless File.file?(@ca_file)
|
238
|
+
msg = "Does not exist or cannot open ca file: #{@ca_file}"
|
239
|
+
logger.error msg
|
240
|
+
raise StandardError, msg
|
241
|
+
end
|
242
|
+
|
243
|
+
# setting the cert_bundle_path
|
244
|
+
logger.info "using cert_bundle_path #{@ca_file}"
|
245
|
+
end
|
246
|
+
|
247
|
+
def create_resource_principal_signer
|
248
|
+
logger.info 'creating resource principal'
|
249
|
+
add_rp_env_override
|
250
|
+
OCI::Auth::Signers.resource_principals_signer
|
251
|
+
rescue StandardError => e
|
252
|
+
logger.info("fail to create resource principal with error #{e}")
|
253
|
+
nil
|
254
|
+
end
|
255
|
+
|
256
|
+
def add_rp_env_override
|
257
|
+
env_file = ENV['LOCAL_TEST_ENV_FILE'] || PUBLIC_RESOURCE_PRINCIPAL_ENV_FILE
|
258
|
+
|
259
|
+
resource_principal_env = {}
|
260
|
+
|
261
|
+
raise 'resource principal env file does not exist' unless File.exist? env_file
|
262
|
+
|
263
|
+
file = File.readlines(env_file)
|
264
|
+
file.each do |env|
|
265
|
+
a = env.split('=')
|
266
|
+
resource_principal_env[a[0]] = a[1].chomp
|
267
|
+
end
|
268
|
+
|
269
|
+
logger.info("resource principal env is setup with #{resource_principal_env}")
|
270
|
+
ENV.update resource_principal_env
|
271
|
+
end
|
272
|
+
|
273
|
+
def create_instance_principal_signer
|
274
|
+
endpoint = @federation_endpoint_override || get_federation_endpoint(@region)
|
275
|
+
|
276
|
+
unless endpoint.nil?
|
277
|
+
logger.info "create instance principal with federation_endpoint = #{endpoint}, cert_bundle #{@ca_file}"
|
278
|
+
end
|
279
|
+
|
280
|
+
::OCI::Auth::Signers::InstancePrincipalsSecurityTokenSigner.new(
|
281
|
+
federation_endpoint: endpoint, federation_client_cert_bundle: @ca_file
|
282
|
+
)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
# fluent-plugin-oci-logging version 1.0.
|
2
|
+
#
|
3
|
+
# Copyright (c) 2021, Oracle and/or its affiliates.
|
4
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
require 'etc'
|
9
|
+
require 'securerandom'
|
10
|
+
require 'oci'
|
11
|
+
|
12
|
+
module Fluent
|
13
|
+
module Plugin
|
14
|
+
# Common utility methods
|
15
|
+
module PublicLoggingUtils
|
16
|
+
PUBLIC_CLIENT_SPEC_VERSION = '1.0'
|
17
|
+
PUBLIC_LOGGING_PREFIX = 'com.oraclecloud.logging.custom.'
|
18
|
+
|
19
|
+
##
|
20
|
+
# Build the wrapper for all the log entries to be sent to lumberjack.
|
21
|
+
#
|
22
|
+
# @return [OCI::LoggingClient::Models::PutLogsDetails] PutLogsDetails wrapper to be filled with log entries
|
23
|
+
def get_put_logs_details_request
|
24
|
+
request = OCI::Loggingingestion::Models::PutLogsDetails.new
|
25
|
+
request.specversion = PUBLIC_CLIENT_SPEC_VERSION
|
26
|
+
request
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Build the requests to be sent to the Lumberjack endpoint.
|
31
|
+
#
|
32
|
+
# @param [Time] time Fluentd event time (may be different from event's
|
33
|
+
# timestamp)
|
34
|
+
# @param [Hash] record The fluentd record.
|
35
|
+
# @param [String] tagpath The fluentd path if populated.
|
36
|
+
# @param [Hash] log_batches_map List of pre-existing log batch.
|
37
|
+
# @param [String] sourceidentifier The fluentd contianing the source path.
|
38
|
+
#
|
39
|
+
# @return [Array] requests List of requests for Lumberjack's backend.
|
40
|
+
def build_request(time, record, tagpath, log_batches_map, sourceidentifier)
|
41
|
+
log = @log || Logger.new($stdout)
|
42
|
+
content = flatten_hash(record)
|
43
|
+
|
44
|
+
# create lumberjack request records
|
45
|
+
logentry = ::OCI::Loggingingestion::Models::LogEntry.new
|
46
|
+
logentry.time = Time.at(time).strftime('%FT%T.%LZ')
|
47
|
+
begin
|
48
|
+
logentry.data = content.to_json
|
49
|
+
rescue StandardError
|
50
|
+
begin
|
51
|
+
log.warn('ruby "to_json" expected UTF-8 encoding will retry parsing with forced encoding')
|
52
|
+
# json requires UTF-8 encoding some logs may not follow that format so we need to fix that
|
53
|
+
content = encode_to_utf8(content)
|
54
|
+
logentry.data = content.to_json
|
55
|
+
rescue StandardError
|
56
|
+
log.warn('unexpected encoding in the log request, will send log as a string instead of json')
|
57
|
+
# instead of loosing data because of an unknown encoding issue send the data as a string
|
58
|
+
logentry.data = content.to_s
|
59
|
+
end
|
60
|
+
end
|
61
|
+
logentry.id = SecureRandom.uuid
|
62
|
+
|
63
|
+
requestkey = tagpath + sourceidentifier
|
64
|
+
|
65
|
+
unless log_batches_map.key?(requestkey)
|
66
|
+
log_entry_batch = OCI::Loggingingestion::Models::LogEntryBatch.new
|
67
|
+
log_entry_batch.source = @hostname
|
68
|
+
log_entry_batch.type = PUBLIC_LOGGING_PREFIX + tagpath
|
69
|
+
log_entry_batch.subject = sourceidentifier
|
70
|
+
log_entry_batch.defaultlogentrytime = Time.at(time).strftime('%FT%T.%LZ')
|
71
|
+
log_entry_batch.entries = []
|
72
|
+
|
73
|
+
log_batches_map[requestkey] = log_entry_batch
|
74
|
+
end
|
75
|
+
|
76
|
+
log_batches_map[requestkey].entries << logentry
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# Send prebuilt requests to the logging endpoint.
|
81
|
+
#
|
82
|
+
# @param [Hash] log_batches_map
|
83
|
+
def send_requests(log_batches_map)
|
84
|
+
log = @log || Logger.new($stdout) # for testing
|
85
|
+
|
86
|
+
request = get_put_logs_details_request
|
87
|
+
|
88
|
+
request.log_entry_batches = log_batches_map.values
|
89
|
+
begin
|
90
|
+
resp = @client.put_logs(@log_object_id, request)
|
91
|
+
rescue OCI::Errors::ServiceError => e
|
92
|
+
log.error "Service Error received sending request: #{e}"
|
93
|
+
if e.status_code == 400
|
94
|
+
log.info 'Eating service error as it is caused by Bad Request[400 HTTP code]'
|
95
|
+
else
|
96
|
+
log.error "Throwing service error for status code:#{e.status_code} as we want fluentd to re-try"
|
97
|
+
raise
|
98
|
+
end
|
99
|
+
rescue OCI::Errors::NetworkError => e
|
100
|
+
log.error "Network Error received sending request: #{e}"
|
101
|
+
if e.code == 400
|
102
|
+
log.info 'Eating network error as it is caused by Bad Request[400 HTTP code]'
|
103
|
+
else
|
104
|
+
log.error "Throwing network error for code:#{e.code} as we want fluentd to re-try"
|
105
|
+
raise
|
106
|
+
end
|
107
|
+
rescue StandardError => e
|
108
|
+
log.error "Standard Error received sending request: #{e}"
|
109
|
+
raise
|
110
|
+
end
|
111
|
+
request.log_entry_batches.each do |batch|
|
112
|
+
log.info "log batch type #{batch.type}, log batch subject #{batch.subject}, size #{batch.entries.size}"
|
113
|
+
end
|
114
|
+
|
115
|
+
log.info "response #{resp.status} id: #{resp.request_id}"
|
116
|
+
end
|
117
|
+
|
118
|
+
##
|
119
|
+
# Flatten the keys of a hash.
|
120
|
+
#
|
121
|
+
# @param [Hash] record The hash object to flatten.
|
122
|
+
#
|
123
|
+
# @return [Hash] The updated, flattened, hash.
|
124
|
+
def flatten_hash(record)
|
125
|
+
record.each_with_object({}) do |(k, v), h|
|
126
|
+
if v.is_a? Hash
|
127
|
+
flatten_hash(v).map { |h_k, h_v| h["#{k}.#{h_k}"] = h_v }
|
128
|
+
elsif k == 'log'
|
129
|
+
h['msg'] = v
|
130
|
+
else
|
131
|
+
h[k] = v
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Force all the string values in the hash to be encoded to UTF-8.
|
138
|
+
#
|
139
|
+
# @param [Hash] record the flattened hash needing to have the encoding changes
|
140
|
+
#
|
141
|
+
# @return [Hash] The updated hash.
|
142
|
+
def encode_to_utf8(record)
|
143
|
+
# the reason for using ISO-8859-1 is that it covers most of the out
|
144
|
+
# of band characters other encoding's don't have this way we can
|
145
|
+
# encode it to a known value and then encode it back into UTF-8
|
146
|
+
record.transform_values { |v| v.to_s.force_encoding('ISO-8859-1').encode('UTF-8') }
|
147
|
+
end
|
148
|
+
|
149
|
+
##
|
150
|
+
# Parse out the log_type from the chunk metadata tag
|
151
|
+
#
|
152
|
+
# @param [String] rawtag the string of the chunk metadata tag that needs to be parsed
|
153
|
+
#
|
154
|
+
# @return [String] take out the tag after the first '.' character or return the whole tag if there is no '.'
|
155
|
+
def get_modified_tag(rawtag)
|
156
|
+
tag = rawtag || 'empty'
|
157
|
+
tag.split('.').length > 1 ? tag.partition('.')[2] : tag
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# Return the correct oci configuration file path for linux platforms.
|
162
|
+
#
|
163
|
+
# @return [String] path to the configuration file
|
164
|
+
def self.determine_linux_config_path
|
165
|
+
managed_agent = '/etc/unified-monitoring-agent/.oci/config'
|
166
|
+
unmanaged_agent = File.join(Dir.home, '.oci/config')
|
167
|
+
config = File.file?(managed_agent) ? managed_agent : unmanage_agent
|
168
|
+
return config
|
169
|
+
rescue StandardError
|
170
|
+
return unmanaged_agent
|
171
|
+
end
|
172
|
+
|
173
|
+
##
|
174
|
+
# Return the correct oci configuration file path for windows platforms.
|
175
|
+
#
|
176
|
+
# @return [String] path to the configuration file
|
177
|
+
def self.determine_windows_config_path
|
178
|
+
managed_agent = 'C:\\oracle_unified_agent\\.oci\\config'
|
179
|
+
unmanaged_agent = File.join("C:\\Users\\#{Etc.getlogin}\\.oci\\config")
|
180
|
+
config = File.file?(managed_agent) ? managed_agent : unmanage_agent
|
181
|
+
return config
|
182
|
+
rescue StandardError
|
183
|
+
return unmanaged_agent
|
184
|
+
end
|
185
|
+
|
186
|
+
##
|
187
|
+
# Return the correct oci configuration user profile for auth
|
188
|
+
#
|
189
|
+
# @param [String] linux_cfg Path to linux configuration file
|
190
|
+
# @param [String] windows_cfg Path to windows configuration file
|
191
|
+
#
|
192
|
+
# @return [String] username to use
|
193
|
+
def self.determine_config_profile_name(linux_cfg, windows_cfg)
|
194
|
+
managed_agent='UNIFIED_MONITORING_AGENT'
|
195
|
+
unmanaged_agent='DEFAULT'
|
196
|
+
location = OS.windows? ? windows_cfg : linux_cfg
|
197
|
+
if location.start_with?('/etc/unified-monitoring-agent', 'C:\\oracle_unified_agent')
|
198
|
+
return managed_agent
|
199
|
+
end
|
200
|
+
oci_config = OCI::ConfigFileLoader.load_config(config_file_location: location)
|
201
|
+
oci_config.profile
|
202
|
+
rescue StandardError
|
203
|
+
unmanaged_agent
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# fluent-plugin-oci-logging version 1.0.
|
2
|
+
#
|
3
|
+
# Copyright (c) 2021, Oracle and/or its affiliates.
|
4
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
# Utility class to determine the underlying operating system.
|
9
|
+
module OS
|
10
|
+
def self.windows?
|
11
|
+
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.mac?
|
15
|
+
(/darwin/ =~ RUBY_PLATFORM) != nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.unix?
|
19
|
+
!OS.windows?
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.linux?
|
23
|
+
unix? and !mac?
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.ubuntu?
|
27
|
+
linux? and os_name_ubuntu?
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.os_name_ubuntu?
|
31
|
+
os_name = 'not_found'
|
32
|
+
file_name = '/etc/os-release'
|
33
|
+
if File.exists?(file_name)
|
34
|
+
IO.foreach(file_name).each do |line|
|
35
|
+
if line.start_with?('ID=')
|
36
|
+
os_name = line.split('=')[1].strip
|
37
|
+
end
|
38
|
+
end
|
39
|
+
else
|
40
|
+
logger.info('Unknown linux distribution detected')
|
41
|
+
end
|
42
|
+
os_name == 'ubuntu' ? true : false
|
43
|
+
rescue StandardError => e
|
44
|
+
log.error "Unable to detect ubuntu platform due to: #{e.message}"
|
45
|
+
false
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# fluent-plugin-oci-logging version 1.0.
|
2
|
+
#
|
3
|
+
# Copyright (c) 2021, Oracle and/or its affiliates.
|
4
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
require_relative 'logging_utils'
|
9
|
+
require_relative 'logging_setup'
|
10
|
+
require 'socket'
|
11
|
+
|
12
|
+
module Fluent
|
13
|
+
module Plugin
|
14
|
+
# OCI Logging Fluentd Output plugin
|
15
|
+
class OCILoggingOutput < Fluent::Plugin::Output
|
16
|
+
include Fluent::Plugin::PublicLoggingUtils
|
17
|
+
include Fluent::Plugin::PublicLoggingSetup
|
18
|
+
|
19
|
+
Fluent::Plugin.register_output('oci_logging', self)
|
20
|
+
|
21
|
+
# allow instance metadata to be configurable (for testing)
|
22
|
+
config_param :metadata_override, :hash, default: nil
|
23
|
+
|
24
|
+
# Path to the PEM CA certificate file for TLS. Can contain several CA certs.
|
25
|
+
# We are defaulting to '/etc/oci-pki/ca-bundle.pem'
|
26
|
+
# This can be overriden for testing.
|
27
|
+
config_param :ca_file, :string, default: PUBLIC_DEFAULT_LINUX_CA_PATH
|
28
|
+
|
29
|
+
# Override to manually provide the host endpoint
|
30
|
+
config_param :logging_endpoint_override, :string, default: nil
|
31
|
+
|
32
|
+
# Override to manually provide the federation endpoint
|
33
|
+
config_param :federation_endpoint_override, :string, default: nil
|
34
|
+
|
35
|
+
# The only required parameter used to identify where we are sending logs for LJ
|
36
|
+
config_param :log_object_id, :string
|
37
|
+
|
38
|
+
# optional forced override for debugging, testing, and potential custom configurations
|
39
|
+
config_param :principal_override, :string, default: nil
|
40
|
+
|
41
|
+
attr_accessor :client, :hostname
|
42
|
+
|
43
|
+
helpers :event_emitter
|
44
|
+
|
45
|
+
def configure(conf)
|
46
|
+
super
|
47
|
+
log.debug 'determining the signer type'
|
48
|
+
|
49
|
+
oci_config, signer_type = get_signer_type(principal_override: @principal_override)
|
50
|
+
signer = get_signer(oci_config, signer_type)
|
51
|
+
log.info "using authentication principal #{signer_type}"
|
52
|
+
|
53
|
+
@client = OCI::Loggingingestion::LoggingClient.new(
|
54
|
+
config: oci_config,
|
55
|
+
endpoint: get_logging_endpoint(@region, logging_endpoint_override: @logging_endpoint_override),
|
56
|
+
signer: signer,
|
57
|
+
proxy_settings: nil,
|
58
|
+
retry_config: nil
|
59
|
+
)
|
60
|
+
|
61
|
+
@client.api_client.request_option_overrides = { ca_file: @ca_file }
|
62
|
+
end
|
63
|
+
|
64
|
+
def start
|
65
|
+
super
|
66
|
+
log.debug 'start'
|
67
|
+
end
|
68
|
+
|
69
|
+
#### Sync Buffered Output ##############################
|
70
|
+
# Implement write() if your plugin uses a normal buffer.
|
71
|
+
########################################################
|
72
|
+
def write(chunk)
|
73
|
+
log.debug "writing chunk metadata #{chunk.metadata}", \
|
74
|
+
dump_unique_id_hex(chunk.unique_id)
|
75
|
+
log_batches_map = {}
|
76
|
+
|
77
|
+
# For standard chunk format (without #format() method)
|
78
|
+
chunk.each do |time, record|
|
79
|
+
begin
|
80
|
+
tag = get_modified_tag(chunk.metadata.tag)
|
81
|
+
source_identifier = record.key?('tailed_path') ? record['tailed_path'] : ''
|
82
|
+
build_request(time, record, tag, log_batches_map, source_identifier)
|
83
|
+
rescue StandardError => e
|
84
|
+
log.error(e.full_message)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
send_requests(log_batches_map) # flush data
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/lib/version.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# fluent-plugin-oci-logging version 1.0.
|
2
|
+
#
|
3
|
+
# Copyright (c) 2021, Oracle and/or its affiliates.
|
4
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
require 'open3'
|
9
|
+
|
10
|
+
def number_of_commits
|
11
|
+
tstamp = Time.now.utc.strftime('%Y%m%d%H%M%S').to_s
|
12
|
+
cmd = 'git log --pretty=oneline | wc -l'
|
13
|
+
stdout_str, stderr_str, status = Open3.capture3(cmd)
|
14
|
+
status.success? ? stdout_str.strip() : "rc-#{tstamp}"
|
15
|
+
end
|
16
|
+
|
17
|
+
module OCILogging
|
18
|
+
MAJOR=1
|
19
|
+
MINOR=0
|
20
|
+
PATCH=number_of_commits
|
21
|
+
VERSION = ENV['OCI_LOGGING_GEM_VERSION'] || "#{MAJOR}.#{MINOR}.#{PATCH}"
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-oci-logging
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- OCI Observability Team
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-06-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fluentd
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.12.3
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.12.3
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: oci
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.12'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.12'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: retriable
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.1.2
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.1.2
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mocha
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.9'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.9'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '13.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '13.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop-rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.5'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.5'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: simplecov
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.17'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.17'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: test-unit
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '3.0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '3.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: webmock
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '3.0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '3.0'
|
153
|
+
description: 'Oracle Observability FluentD Plugins : Logging output plugin for OCI
|
154
|
+
logging'
|
155
|
+
email:
|
156
|
+
- no-reply@support.oracle.com
|
157
|
+
executables: []
|
158
|
+
extensions: []
|
159
|
+
extra_rdoc_files:
|
160
|
+
- README.md
|
161
|
+
files:
|
162
|
+
- README.md
|
163
|
+
- lib/fluent/plugin/logging_setup.rb
|
164
|
+
- lib/fluent/plugin/logging_utils.rb
|
165
|
+
- lib/fluent/plugin/os.rb
|
166
|
+
- lib/fluent/plugin/out_oci_logging.rb
|
167
|
+
- lib/version.rb
|
168
|
+
homepage: https://docs.cloud.oracle.com/en-us/iaas/Content/Logging/Concepts/loggingoverview.htm
|
169
|
+
licenses:
|
170
|
+
- UPL-1.0
|
171
|
+
- Apache-2.0
|
172
|
+
metadata:
|
173
|
+
source_code_uri: https://github.com/oracle/fluent-plugin-oci-logging
|
174
|
+
post_install_message:
|
175
|
+
rdoc_options: []
|
176
|
+
require_paths:
|
177
|
+
- lib
|
178
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
requirements: []
|
189
|
+
rubygems_version: 3.2.15
|
190
|
+
signing_key:
|
191
|
+
specification_version: 4
|
192
|
+
summary: OCI Fluentd Logging output plugin following Unified Schema
|
193
|
+
test_files: []
|