Skip to content

Commit 800f70e

Browse files
adding timezone field, header opc_meta_data property, and workload identity auth method (#19)
Co-authored-by: IMDADMI <[email protected]>
1 parent 387f795 commit 800f70e

File tree

11 files changed

+111
-26
lines changed

11 files changed

+111
-26
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Change Log
22

3+
## 2.0.7 - 2024-10-10
4+
### Added
5+
- Support for timezone override for logs where timezone identifier is missing
6+
- Support for Workload Identity based authorization
7+
38
## 2.0.6 - 2024-02-05
49
### Added
510
- Support for endpoint override for instance principal auth mode.

Gemfile

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
## Copyright (c) 2021, 2022 Oracle and/or its affiliates.
1+
## Copyright (c) 2021, 2024 Oracle and/or its affiliates.
22
## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
33

44
source "https://rubygems.org"
5-
65
gemspec
7-

examples/apache.conf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<record>
3434
oci_la_global_metadata ${{<key1>: <value1>, <key2>:<value2>}}
3535
oci_la_entity_id <LOGGING_ANALYTICS_ENTITY_OCID> # If same across sources. Else keep this in individual filters
36-
oci_la_entity_type <LOGGING_ANALYTICS_ENTITY_TYPE> # If same across sources. Else keep this in individual filters
36+
oci_la_entity_type <LOGGING_ANALYTICS_ENTITY_TYPE> # If same across sources. Else keep this in individual filters
3737
</record>
3838
</filter>
3939

@@ -45,21 +45,21 @@
4545
oci_la_log_source_name <LOGGING_ANALYTICS_SOURCENAME>
4646
oci_la_log_group_id <LOGGING_ANALYTICS_LOGGROUP_OCID>
4747
oci_la_log_path "${record['tailed_path']}"
48+
oci_la_timezone <TIMEZONE>
4849
tag ${tag}
4950
</record>
5051
</filter>
5152

5253
<match oci.**>
5354
@type oci-logging-analytics
5455
namespace <YOUR_OCI_TENANCY_NAMESPACE>
55-
# Auth config file details
5656
config_file_location ~/.oci/config
5757
profile_name DEFAULT
5858
# Buffer Configuration
5959
<buffer>
6060
@type file
61-
path /var/log
61+
path /var/log
6262
retry_forever true
6363
disable_chunk_backup true
6464
</buffer>
65-
</match>
65+
</match>

fluent-plugin-oci-logging-analytics.gemspec

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
## Copyright (c) 2021, 2022 Oracle and/or its affiliates.
1+
## Copyright (c) 2021, 2024 Oracle and/or its affiliates.
22
## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
3+
require_relative './lib/fluent/version/version'
34

45
lib = File.expand_path("../lib", __FILE__)
56
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
67

78
Gem::Specification.new do |spec|
89
spec.name = "fluent-plugin-oci-logging-analytics"
9-
spec.version = "2.0.6"
10+
spec.version = Version::VERSION
1011
spec.authors = ["Oracle","OCI Observability: Logging Analytics"]
1112
spec.email = ["[email protected]"]
1213

lib/fluent/dto/logEvents.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
## Copyright (c) 2021, 2022 Oracle and/or its affiliates.
1+
## Copyright (c) 2021, 2024 Oracle and/or its affiliates.
22
## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
33

44
class LogEvents
5-
attr_accessor :entityId, :entityType, :logSourceName, :logPath, :logRecords , :metadata
5+
attr_accessor :entityId, :entityType, :logSourceName, :logPath, :logRecords , :metadata, :timezone
66
def initialize(lrpe_key, fluentd_records)
7-
@metadata, @entityId, @entityType, @logSourceName, @logPath = lrpe_key
7+
@metadata, @entityId, @entityType, @logSourceName, @logPath, @timezone = lrpe_key
88
@logRecords = fluentd_records.map{ |record|
99
record['message']
1010
}
@@ -17,8 +17,9 @@ def to_hash
1717
entityType: @entityType,
1818
logSourceName: @logSourceName,
1919
logPath: @logPath,
20-
logRecords: @logRecords
20+
logRecords: @logRecords,
21+
timezone:@timezone
2122
}.compact
2223
end
23-
24+
2425
end

lib/fluent/dto/logEventsJson.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## Copyright (c) 2021, 2022 Oracle and/or its affiliates.
1+
## Copyright (c) 2021, 2024 Oracle and/or its affiliates.
22
## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
33

44
require_relative './logEvents'
@@ -20,5 +20,5 @@ def to_hash
2020
end
2121
}.compact
2222
end
23-
23+
2424
end

lib/fluent/enums/source.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## Copyright (c) 2024 Oracle and/or its affiliates.
2+
## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
3+
4+
module Source
5+
FLUENTD = :fluentd
6+
KUBERNETES_SOLUTION = :kubernetes_solution
7+
end

lib/fluent/metrics/metricsLabels.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
## Copyright (c) 2021, 2024 Oracle and/or its affiliates.
2+
## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
3+
14
class MetricsLabels
2-
attr_accessor :worker_id, :tag, :logGroupId, :logSourceName, :logSet, :invalid_reason, :records_valid, :records_per_tag, :latency
5+
attr_accessor :worker_id, :tag, :logGroupId, :logSourceName, :logSet, :invalid_reason, :records_valid, :records_per_tag, :latency,:timezone
36
def initialize
47
@worker_id = nil
58
@tag = nil
@@ -10,5 +13,6 @@ def initialize
1013
@records_valid = 0
1114
@records_per_tag = 0
1215
@latency = 0
16+
@timezone = nil
1317
end
14-
end
18+
end

lib/fluent/metrics/prometheusMetrics.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## Copyright (c) 2021, 2024 Oracle and/or its affiliates.
2+
## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
3+
14
require 'prometheus/client'
25
require 'prometheus/client/registry'
36
require 'prometheus/client/gauge'
@@ -35,4 +38,4 @@ def registerMetrics
3538
registry.register(@chunk_time_to_receive) unless registry.exist?('oci_la_fluentd_output_plugin_chunk_time_to_receive')
3639
registry.register(@chunk_time_to_upload) unless registry.exist?('oci_la_fluentd_output_plugin_chunk_time_to_post')
3740
end
38-
end
41+
end

lib/fluent/plugin/out_oci-logging-analytics.rb

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## Copyright (c) 2021, 2022 Oracle and/or its affiliates.
1+
## Copyright (c) 2021, 2024 Oracle and/or its affiliates.
22
## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
33

44
require 'fluent/plugin/output'
@@ -7,11 +7,13 @@
77
require 'yajl'
88
require 'yajl/json_gem'
99

10+
# require 'tzinfo'
1011
require 'logger'
1112
require_relative '../dto/logEventsJson'
1213
require_relative '../dto/logEvents'
1314
require_relative '../metrics/prometheusMetrics'
1415
require_relative '../metrics/metricsLabels'
16+
require_relative '../enums/source'
1517

1618
# Import only specific OCI modules to improve load times and reduce the memory requirements.
1719
require 'oci/auth/auth'
@@ -36,7 +38,6 @@
3638
require 'oci/waiter'
3739
require 'oci/retry/retry'
3840
require 'oci/object_storage/object_storage'
39-
4041
module OCI
4142
class << self
4243
attr_accessor :sdk_name
@@ -97,7 +98,8 @@ class OutOracleOCILogAnalytics < Output
9798
config_param :zip_file_location, :string, :default => nil
9899
desc 'The kubernetes_metadata_keys_mapping.'
99100
config_param :kubernetes_metadata_keys_mapping, :hash, :default => {"container_name":"Container","namespace_name":"Namespace","pod_name":"Pod","container_image":"Container Image Name","host":"Node"}
100-
101+
desc 'opc-meta-properties'
102+
config_param :collection_source, :string, :default => Source::FLUENTD
101103

102104
#****************************************************************
103105
desc 'The http proxy to be used.'
@@ -256,6 +258,14 @@ def initialize_loganalytics_client()
256258
else
257259
@@loganalytics_client = OCI::LogAnalytics::LogAnalyticsClient.new(config: OCI::Config.new, signer: instance_principals_signer)
258260
end
261+
when "WorkloadIdentity"
262+
workload_identity_signer = OCI::Auth::Signers::oke_workload_resource_principal_signer
263+
if is_valid(@endpoint)
264+
@@loganalytics_client = OCI::LogAnalytics::LogAnalyticsClient.new(config: OCI::Config.new, endpoint: @endpoint, signer: workload_identity_signer)
265+
@@logger.info {"loganalytics_client initialised with endpoint: #{@endpoint}"}
266+
else
267+
@@loganalytics_client = OCI::LogAnalytics::LogAnalyticsClient.new(config: OCI::Config.new, signer: workload_identity_signer)
268+
end
259269
when "ConfigFile"
260270
my_config = OCI::ConfigFileLoader.load_config(config_file_location: @config_file_location, profile_name: @profile_name)
261271
if is_valid(@endpoint)
@@ -628,6 +638,8 @@ def group_by_logGroupId(chunk)
628638
latency = 0
629639
records_per_tag = 0
630640

641+
642+
631643
tag_metrics_set = Hash.new
632644
logGroup_labels_set = Hash.new
633645

@@ -637,8 +649,8 @@ def group_by_logGroupId(chunk)
637649
tags_per_logGroupId = Hash.new
638650
tag_logSet_map = Hash.new
639651
tag_metadata_map = Hash.new
652+
timezoneValuesByTag = Hash.new
640653
incoming_records = 0
641-
642654
chunk.each do |time, record|
643655
incoming_records += 1
644656
metricsLabels = MetricsLabels.new
@@ -722,6 +734,8 @@ def group_by_logGroupId(chunk)
722734
end
723735
next
724736
end
737+
738+
# metricsLabels.timezone = record["oci_la_timezone"]
725739
metricsLabels.logGroupId = record["oci_la_log_group_id"]
726740
metricsLabels.logSourceName = record["oci_la_log_source_name"]
727741
if record["oci_la_log_set"] != nil
@@ -770,6 +784,25 @@ def group_by_logGroupId(chunk)
770784
tags_per_logGroupId[record["oci_la_log_group_id"]] = record["tag"]
771785
end
772786
end
787+
# validating the timezone field
788+
if !timezoneValuesByTag.has_key?(record["tag"])
789+
begin
790+
timezoneIdentifier = record["oci_la_timezone"]
791+
unless is_valid(timezoneIdentifier)
792+
record["oci_la_timezone"] = nil
793+
else
794+
isTimezoneExist = timezone_exist? timezoneIdentifier
795+
unless isTimezoneExist
796+
@@logger.warn { "Invalid timezone '#{timezoneIdentifier}', using default UTC." }
797+
record["oci_la_timezone"] = "UTC"
798+
end
799+
800+
end
801+
timezoneValuesByTag[record["tag"]] = record["oci_la_timezone"]
802+
end
803+
else
804+
record["oci_la_timezone"] = timezoneValuesByTag[record["tag"]]
805+
end
773806

774807
records << record
775808
ensure
@@ -916,6 +949,14 @@ def write(chunk)
916949
end
917950
end
918951
end
952+
def timezone_exist?(tz)
953+
begin
954+
TZInfo::Timezone.get(tz)
955+
return true
956+
rescue TZInfo::InvalidTimezoneIdentifier
957+
return false
958+
end
959+
end
919960

920961
# Each oci_la_log_set will correspond to a separate file in the zip
921962
# Only MAX_FILES_PER_ZIP files are allowed per zip.
@@ -958,6 +999,21 @@ def get_logSets_map_per_logGroupId(oci_la_log_group_id,records_per_logGroupId)
958999

9591000
# takes a fluentD chunk and converts it to an in-memory zipfile, populating metrics hash provided
9601001
# Any exception raised is passed into the metrics hash, to be re-thrown from write()
1002+
def getCollectionSource(input)
1003+
collections_src = []
1004+
if !is_valid input
1005+
collections_src.unshift("source:#{Source::FLUENTD}")
1006+
else
1007+
if input == Source::FLUENTD.to_s or input == Source::KUBERNETES_SOLUTION.to_s
1008+
collections_src.unshift("source:#{input}")
1009+
else
1010+
# source not define ! using default source 'fluentd'
1011+
collections_src.unshift("source:#{Source::FLUENTD}")
1012+
end
1013+
end
1014+
collections_src
1015+
end
1016+
9611017
def get_zipped_stream(oci_la_log_group_id,oci_la_global_metadata,records_per_logSet_map)
9621018
begin
9631019
current, = Time.now
@@ -970,8 +1026,9 @@ def get_zipped_stream(oci_la_log_group_id,oci_la_global_metadata,records_per_log
9701026
record['oci_la_metadata'],
9711027
record['oci_la_entity_id'],
9721028
record['oci_la_entity_type'],
973-
record['oci_la_log_source_name'] ,
974-
record['oci_la_log_path']
1029+
record['oci_la_log_source_name'],
1030+
record['oci_la_log_path'],
1031+
record['oci_la_timezone']
9751032
]}.map { |lrpe_key, records_per_lrpe|
9761033
number_of_records += records_per_lrpe.length
9771034
LogEvents.new(lrpe_key, records_per_lrpe)
@@ -1021,9 +1078,10 @@ def save_zip_to_local(oci_la_log_group_id, zippedstream, current_s)
10211078
# upload zipped stream to oci
10221079
def upload_to_oci(oci_la_log_group_id, number_of_records, zippedstream, metricsLabels_array)
10231080
begin
1081+
collection_src_prop = getCollectionSource @collection_source
10241082
error_reason = nil
10251083
error_code = nil
1026-
opts = {payload_type: "ZIP"}
1084+
opts = { payload_type: "ZIP", opc_meta_properties:collection_src_prop}
10271085

10281086
response = @@loganalytics_client.upload_log_events_file(namespace_name=@namespace,
10291087
logGroupId=oci_la_log_group_id ,

lib/fluent/version/version.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## Copyright (c) 2024 Oracle and/or its affiliates.
2+
## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
3+
4+
# frozen_string_literal: true
5+
6+
module Version
7+
VERSION = "2.0.7".freeze
8+
end

0 commit comments

Comments
 (0)