fluent-plugin-oci-logging-analytics 2.0.0 → 2.0.4

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
- SHA256:
3
- metadata.gz: dde9a7a3e6be01a2556efa148f43934c2c723ffce544d3c11af1c50fe46f06b7
4
- data.tar.gz: b442ff6c28ef6bc1c3ddc6d74c6b48e30c9921902607f9581c0aa116e5ba9db2
2
+ SHA1:
3
+ metadata.gz: b2c10b68eefbf373de236156362383500f9746a9
4
+ data.tar.gz: 6ad63e3893634f360387c68b03248291d787d33f
5
5
  SHA512:
6
- metadata.gz: a106761ec570d6c14435544617bf2357846b022869ef7c6154463b848cf72eeedbc96080a7d819911518818864379655aaa7668c4bad46d4d45a80a10dffc40f
7
- data.tar.gz: dd7fcd53fd707c1c365cd8c5cbe1f4d6612d27b0de201d9ed2e1a98235322b08cdb7c4d15f968fa3bc667175e226cae1022673c36ba6409ee73bbe0e703417aa
6
+ metadata.gz: fcb93cdf4da13e23101127320bec26bb96ac3426e2fe34402591febfc1e0ab8494a253e8c089f0bcd13aafea35b740ea353ee164213d89d415fe93a07d8764e2
7
+ data.tar.gz: 83115a796e9baf6311c3d3da4f9f137fdbd4cbb74bb52f10a3686cc8441f26315c38522bb32c1acc06652aaae92bd7a1adff643f555df91de11a4b1e84487355
@@ -1,3 +1,5 @@
1
+ ## Copyright (c) 2021, 2022 Oracle and/or its affiliates.
2
+ ## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
1
3
 
2
4
  class LogEvents
3
5
  attr_accessor :entityId, :entityType, :logSourceName, :logPath, :logRecords , :metadata
@@ -1,3 +1,5 @@
1
+ ## Copyright (c) 2021, 2022 Oracle and/or its affiliates.
2
+ ## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
1
3
 
2
4
  require_relative './logEvents'
3
5
 
@@ -1,11 +1,13 @@
1
1
  class MetricsLabels
2
- attr_accessor :tag, :logGroupId, :logSourceName, :logSet, :drop_reason, :records_valid
2
+ attr_accessor :tag, :logGroupId, :logSourceName, :logSet, :invalid_reason, :records_valid, :records_per_tag, :latency
3
3
  def initialize
4
4
  @tag = nil
5
5
  @logGroupId = nil
6
6
  @logSourceName = nil
7
7
  @logSet = nil
8
- @drop_reason = nil
8
+ @invalid_reason = nil
9
9
  @records_valid = 0
10
+ @records_per_tag = 0
11
+ @latency = 0
10
12
  end
11
13
  end
@@ -6,36 +6,36 @@ require 'singleton'
6
6
 
7
7
  class PrometheusMetrics
8
8
  include Singleton
9
- attr_accessor :records_received, :records_valid, :records_dropped, :records_error, :records_posted,
10
- :bytes_received, :bytes_posted, :latency_avg, :chunk_upload_time_taken
9
+ attr_accessor :records_received, :records_valid, :records_invalid, :records_error, :records_posted,
10
+ :bytes_received, :bytes_posted, :chunk_time_to_receive, :chunk_time_to_upload
11
11
  def initialize
12
12
  createMetrics
13
13
  registerMetrics
14
14
  end
15
15
  def createMetrics
16
16
  gauge = Prometheus::Client::Gauge
17
- @records_received = gauge.new(:oci_logging_analytics_records_received, docstring: '...', labels: [:tag,:logGroupId,:logSourceName,:logSet])
18
- @records_valid = gauge.new(:oci_logging_analytics_records_valid, docstring: '...', labels: [:tag,:logGroupId,:logSourceName,:logSet])
19
- @records_dropped = gauge.new(:oci_logging_analytics_records_dropped, docstring: '...', labels: [:tag,:logGroupId,:logSourceName,:logSet,:drop_reason])
20
- @records_error = gauge.new(:oci_logging_analytics_records_error, docstring: '...', labels: [:tag,:logGroupId,:logSourceName,:logSet,:error_code, :error_reason])
21
- @records_posted = gauge.new(:oci_logging_analytics_records_posted, docstring: '...', labels: [:tag,:logGroupId,:logSourceName,:logSet])
22
- @bytes_received = gauge.new(:oci_logging_analytics_bytes_received, docstring: '...', labels: [:tag])
23
- @bytes_posted = gauge.new(:oci_logging_analytics_bytes_posted, docstring: '...', labels: [:logGroupId])
17
+ @records_received = gauge.new(:oci_la_fluentd_output_plugin_records_received, docstring: 'Number of records received by the OCI Logging Analytics Fluentd output plugin.', labels: [:tag,:oci_la_log_group_id,:oci_la_log_source_name,:oci_la_log_set])
18
+ @records_valid = gauge.new(:oci_la_fluentd_output_plugin_records_valid, docstring: 'Number of valid records received by the OCI Logging Analytics Fluentd output plugin.', labels: [:tag,:oci_la_log_group_id,:oci_la_log_source_name,:oci_la_log_set])
19
+ @records_invalid = gauge.new(:oci_la_fluentd_output_plugin_records_invalid, docstring: 'Number of invalid records received by the OCI Logging Analytics Fluentd output plugin.', labels: [:tag,:oci_la_log_group_id,:oci_la_log_source_name,:oci_la_log_set,:reason])
20
+ @records_error = gauge.new(:oci_la_fluentd_output_plugin_records_post_error, docstring: 'Number of records failed posting to OCI Logging Analytics by the Fluentd output plugin.', labels: [:tag,:oci_la_log_group_id,:oci_la_log_source_name,:oci_la_log_set,:error_code, :reason])
21
+ @records_posted = gauge.new(:oci_la_fluentd_output_plugin_records_post_success, docstring: 'Number of records posted by the OCI Logging Analytics Fluentd output plugin.', labels: [:tag,:oci_la_log_group_id,:oci_la_log_source_name,:oci_la_log_set])
22
+ #@bytes_received = gauge.new(:oci_la_bytes_received, docstring: '...', labels: [:tag])
23
+ #@bytes_posted = gauge.new(:oci_la_bytes_posted, docstring: '...', labels: [:oci_la_log_group_id])
24
24
  histogram = Prometheus::Client::Histogram
25
- @latency_avg = histogram.new(:oci_logging_analytics_network_latency_avg, docstring: '...', labels: [:tag])
26
- @chunk_upload_time_taken = histogram.new(:oci_logging_analytics_chunk_upload_time_taken, docstring: '...', labels: [:logGroupId])
25
+ @chunk_time_to_receive = histogram.new(:oci_la_fluentd_output_plugin_chunk_time_to_receive, docstring: 'Average time taken by Fluentd to deliver the collected records from Input plugin to OCI Logging Analytics output plugin.', labels: [:tag])
26
+ @chunk_time_to_upload = histogram.new(:oci_la_fluentd_output_plugin_chunk_time_to_post, docstring: 'Average time taken for posting the received records to OCI Logging Analytics by the Fluentd output plugin.', labels: [:oci_la_log_group_id])
27
27
  end
28
28
 
29
29
  def registerMetrics
30
30
  registry = Prometheus::Client.registry
31
- registry.register(@records_received) unless registry.exist?('oci_logging_analytics_records_received')
32
- registry.register(@records_valid) unless registry.exist?('oci_logging_analytics_records_valid')
33
- registry.register(@records_dropped) unless registry.exist?('oci_logging_analytics_records_dropped')
34
- registry.register(@records_error) unless registry.exist?('oci_logging_analytics_records_error')
35
- registry.register(@records_posted) unless registry.exist?('oci_logging_analytics_records_posted')
36
- registry.register(@bytes_received) unless registry.exist?('oci_logging_analytics_bytes_received')
37
- registry.register(@bytes_posted) unless registry.exist?('oci_logging_analytics_bytes_valid')
38
- registry.register(@latency_avg) unless registry.exist?('oci_logging_analytics_network_latency_avg')
39
- registry.register(@chunk_upload_time_taken) unless registry.exist?('oci_logging_analytics_chunk_upload_time_taken')
31
+ registry.register(@records_received) unless registry.exist?('oci_la_fluentd_output_plugin_records_received')
32
+ registry.register(@records_valid) unless registry.exist?('oci_la_fluentd_output_plugin_records_valid')
33
+ registry.register(@records_invalid) unless registry.exist?('oci_la_fluentd_output_plugin_records_invalid')
34
+ registry.register(@records_error) unless registry.exist?('oci_la_fluentd_output_plugin_records_post_error')
35
+ registry.register(@records_posted) unless registry.exist?('oci_la_fluentd_output_plugin_records_post_success')
36
+ #registry.register(@bytes_received) unless registry.exist?('oci_la_bytes_received')
37
+ #registry.register(@bytes_posted) unless registry.exist?('oci_la_bytes_valid')
38
+ registry.register(@chunk_time_to_receive) unless registry.exist?('oci_la_fluentd_output_plugin_chunk_time_to_receive')
39
+ registry.register(@chunk_time_to_upload) unless registry.exist?('oci_la_fluentd_output_plugin_chunk_time_to_post')
40
40
  end
41
41
  end
@@ -1,13 +1,53 @@
1
- ## Copyright (c) 2021 Oracle and/or its affiliates.
1
+ ## Copyright (c) 2021, 2022 Oracle and/or its affiliates.
2
2
  ## The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/
3
3
 
4
4
  require 'fluent/plugin/output'
5
5
  require "benchmark"
6
6
  require 'zip'
7
- require 'oci'
7
+
8
8
  require 'logger'
9
9
  require_relative '../dto/logEventsJson'
10
10
  require_relative '../dto/logEvents'
11
+ require_relative '../metrics/prometheusMetrics'
12
+ require_relative '../metrics/metricsLabels'
13
+
14
+ # Import only specific OCI modules to improve load times and reduce the memory requirements.
15
+ require 'oci/auth/auth'
16
+ require 'oci/log_analytics/log_analytics'
17
+ require 'oci/log_analytics/log_analytics_client'
18
+
19
+ # Workaround until OCI SDK releases a proper fix to load only specific service related modules/client.
20
+ require 'oci/api_client'
21
+ require 'oci/api_client_proxy_settings'
22
+ require 'oci/config'
23
+ require 'oci/config_file_loader'
24
+ require 'oci/errors'
25
+ require 'oci/global_context'
26
+ require 'oci/internal/internal'
27
+ require 'oci/regions'
28
+ require 'oci/regions_definitions'
29
+ require 'oci/response_headers'
30
+ require 'oci/response'
31
+ require 'oci/base_signer'
32
+ require 'oci/signer'
33
+ require 'oci/version'
34
+ require 'oci/waiter'
35
+ require 'oci/retry/retry'
36
+ require 'oci/object_storage/object_storage'
37
+
38
+ module OCI
39
+ class << self
40
+ attr_accessor :sdk_name
41
+
42
+ # Defines the logger used for debugging for the OCI module.
43
+ # For example, log to STDOUT by setting this to Logger.new(STDOUT).
44
+ #
45
+ # @return [Logger]
46
+ attr_accessor :logger
47
+ end
48
+ end
49
+
50
+ OracleBMC = OCI
11
51
 
12
52
  module Fluent::Plugin
13
53
  class OutOracleOCILogAnalytics < Output
@@ -15,8 +55,25 @@ module Fluent::Plugin
15
55
  helpers :thread, :event_emitter
16
56
 
17
57
  MAX_FILES_PER_ZIP = 100
58
+ METRICS_INVALID_REASON_MESSAGE = "MISSING_FIELD_MESSAGE"
59
+ METRICS_INVALID_REASON_LOG_GROUP_ID = "MISSING_OCI_LA_LOG_GROUP_ID_FIELD"
60
+ METRICS_INVALID_REASON_LOG_SOURCE_NAME = "MISSING_OCI_LA_LOG_SOURCE_NAME_FIELD"
61
+
62
+ METRICS_SERVICE_ERROR_REASON_400 = "INVALID_PARAMETER"
63
+ METRICS_SERVICE_ERROR_REASON_401 = "AUTHENTICATION_FAILED"
64
+ METRICS_SERVICE_ERROR_REASON_404 = "AUTHORIZATION_FAILED"
65
+ METRICS_SERVICE_ERROR_REASON_429 = "TOO_MANY_REQUESTES"
66
+ METRICS_SERVICE_ERROR_REASON_500 = "INTERNAL_SERVER_ERROR"
67
+ METRICS_SERVICE_ERROR_REASON_502 = "BAD_GATEWAY"
68
+ METRICS_SERVICE_ERROR_REASON_503 = "SERVICE_UNAVAILABLE"
69
+ METRICS_SERVICE_ERROR_REASON_504 = "GATEWAY_TIMEOUT"
70
+ METRICS_SERVICE_ERROR_REASON_505 = "HTTP_VERSION_NOT_SUPPORTED"
71
+ METRICS_SERVICE_ERROR_REASON_UNKNOWN = "UNKNOWN_ERROR"
72
+
73
+
18
74
  @@logger = nil
19
75
  @@loganalytics_client = nil
76
+ @@prometheusMetrics = nil
20
77
  @@logger_config_errors = []
21
78
 
22
79
 
@@ -214,6 +271,7 @@ module Fluent::Plugin
214
271
 
215
272
  def configure(conf)
216
273
  super
274
+ @@prometheusMetrics = PrometheusMetrics.instance
217
275
  initialize_logger
218
276
 
219
277
  initialize_loganalytics_client
@@ -466,32 +524,36 @@ module Fluent::Plugin
466
524
 
467
525
  def is_valid_record(record_hash,record)
468
526
  begin
527
+ invalid_reason = nil
469
528
  if !record_hash.has_key?("message")
529
+ invalid_reason = OutOracleOCILogAnalytics::METRICS_INVALID_REASON_MESSAGE
470
530
  if record_hash.has_key?("tag")
471
531
  @@logger.warn {"Invalid records associated with tag : #{record["tag"]}. 'message' field is not present in the record."}
472
532
  else
473
533
  @@logger.info {"InvalidRecord: #{record}"}
474
534
  @@logger.warn {"Invalid record. 'message' field is not present in the record."}
475
535
  end
476
- return false
536
+ return false,invalid_reason
477
537
  elsif !record_hash.has_key?("oci_la_log_group_id") || !is_valid(record["oci_la_log_group_id"])
538
+ invalid_reason = OutOracleOCILogAnalytics::METRICS_INVALID_REASON_LOG_GROUP_ID
478
539
  if record_hash.has_key?("tag")
479
540
  @@logger.warn {"Invalid records associated with tag : #{record["tag"]}.'oci_la_log_group_id' must not be empty.
480
541
  Skipping all the records associated with the tag"}
481
542
  else
482
543
  @@logger.warn {"Invalid record.'oci_la_log_group_id' must not be empty"}
483
544
  end
484
- return false
545
+ return false,invalid_reason
485
546
  elsif !record_hash.has_key?("oci_la_log_source_name") || !is_valid(record["oci_la_log_source_name"])
547
+ invalid_reason = OutOracleOCILogAnalytics::METRICS_INVALID_REASON_LOG_SOURCE_NAME
486
548
  if record_hash.has_key?("tag")
487
549
  @@logger.warn {"Invalid records associated with tag : #{record["tag"]}.'oci_la_log_source_name' must not be empty.
488
550
  Skipping all the records associated with the tag"}
489
551
  else
490
552
  @@logger.warn {"Invalid record.'oci_la_log_source_name' must not be empty"}
491
553
  end
492
- return false
554
+ return false,invalid_reason
493
555
  else
494
- return true
556
+ return true,invalid_reason
495
557
  end
496
558
  end
497
559
  end
@@ -542,6 +604,11 @@ module Fluent::Plugin
542
604
  current_f, current_s = current.to_f, current.strftime("%Y%m%dT%H%M%S%9NZ")
543
605
  records = []
544
606
  count = 0
607
+ latency = 0
608
+ records_per_tag = 0
609
+
610
+ tag_metrics_set = Hash.new
611
+ logGroup_labels_set = Hash.new
545
612
 
546
613
  invalid_tag_set = Set.new
547
614
  incoming_records_per_tag = Hash.new
@@ -549,130 +616,166 @@ module Fluent::Plugin
549
616
  tags_per_logGroupId = Hash.new
550
617
  tag_logSet_map = Hash.new
551
618
  tag_metadata_map = Hash.new
619
+ incoming_records = 0
552
620
 
553
621
  chunk.each do |time, record|
554
-
622
+ incoming_records += 1
623
+ metricsLabels = MetricsLabels.new
555
624
  if !record.nil?
556
- record_hash = record.keys.map {|x| [x,true]}.to_h
557
- is_tag_exists = false
558
- if record_hash.has_key?("tag") && is_valid(record["tag"])
559
- is_tag_exists = true
560
- end
625
+ begin
626
+ record_hash = record.keys.map {|x| [x,true]}.to_h
627
+ is_tag_exists = false
628
+ if record_hash.has_key?("tag") && is_valid(record["tag"])
629
+ is_tag_exists = true
630
+ metricsLabels.tag = record["tag"]
631
+ end
561
632
 
562
- if is_tag_exists && incoming_records_per_tag.has_key?(record["tag"])
563
- incoming_records_per_tag[record["tag"]] += 1
564
- elsif is_tag_exists
565
- incoming_records_per_tag[record["tag"]] = 1
566
- end
567
- #For any given tag, if one record fails (mandatory fields validation) then all the records from that source will be ignored
568
- if is_tag_exists && invalid_tag_set.include?(record["tag"])
569
- invalid_records_per_tag[record["tag"]] += 1
570
- next #This tag is already present in the invalid_tag_set, so ignoring the message.
571
- end
572
- #Setting tag/default value for oci_la_log_path, when not provided in config file.
573
- if !record_hash.has_key?("oci_la_log_path") || !is_valid(record["oci_la_log_path"])
574
- if is_tag_exists
575
- record["oci_la_log_path"] = record["tag"]
576
- else
577
- record["oci_la_log_path"] = 'UNDEFINED'
633
+ if is_tag_exists && incoming_records_per_tag.has_key?(record["tag"])
634
+ incoming_records_per_tag[record["tag"]] += 1
635
+ elsif is_tag_exists
636
+ incoming_records_per_tag[record["tag"]] = 1
578
637
  end
579
- end
638
+ #For any given tag, if one record fails (mandatory fields validation) then all the records from that source will be ignored
639
+ if is_tag_exists && invalid_tag_set.include?(record["tag"])
640
+ invalid_records_per_tag[record["tag"]] += 1
641
+ next #This tag is already present in the invalid_tag_set, so ignoring the message.
642
+ end
643
+ #Setting tag/default value for oci_la_log_path, when not provided in config file.
644
+ if !record_hash.has_key?("oci_la_log_path") || !is_valid(record["oci_la_log_path"])
645
+ if is_tag_exists
646
+ record["oci_la_log_path"] = record["tag"]
647
+ else
648
+ record["oci_la_log_path"] = 'UNDEFINED'
649
+ end
650
+ end
580
651
 
581
- #Extracting oci_la_log_set when oci_la_log_set_key and oci_la_log_set_ext_regex is provided.
582
- #1) oci_la_log_set param is not provided in config file and above logic not executed.
583
- #2) Valid oci_la_log_set_key + No oci_la_log_set_ext_regex
584
- #a) Valid key available in record with oci_la_log_set_key corresponding value (oci_la_log_set_key is a key in config file) --> oci_la_log_set
585
- #b) No Valid key available in record with oci_la_log_set_key corresponding value --> nil
586
- #3) Valid key available in record with oci_la_log_set_key corresponding value + Valid oci_la_log_set_ext_regex
587
- #a) Parse success --> parsed oci_la_log_set
588
- #b) Parse failure --> nil (as oci_la_log_set value)
589
- #4) No oci_la_log_set_key --> do nothing --> nil
590
-
591
- #Extracting oci_la_log_set when oci_la_log_set and oci_la_log_set_ext_regex is provided.
592
- #1) Valid oci_la_log_set + No oci_la_log_set_ext_regex --> oci_la_log_set
593
- #2) Valid oci_la_log_set + Valid oci_la_log_set_ext_regex
594
- #a) Parse success --> parsed oci_la_log_set
595
- #b) Parse failure --> nil (as oci_la_log_set value)
596
- #3) No oci_la_log_set --> do nothing --> nil
597
-
598
- unparsed_logSet = nil
599
- processed_logSet = nil
600
- if is_tag_exists && tag_logSet_map.has_key?(record["tag"])
601
- record["oci_la_log_set"] = tag_logSet_map[record["tag"]]
602
- else
603
- if record_hash.has_key?("oci_la_log_set_key")
604
- if is_valid(record["oci_la_log_set_key"]) && record_hash.has_key?(record["oci_la_log_set_key"])
605
- if is_valid(record[record["oci_la_log_set_key"]])
606
- unparsed_logSet = record[record["oci_la_log_set_key"]]
607
- processed_logSet = get_or_parse_logSet(unparsed_logSet,record, record_hash,is_tag_exists)
652
+ #Extracting oci_la_log_set when oci_la_log_set_key and oci_la_log_set_ext_regex is provided.
653
+ #1) oci_la_log_set param is not provided in config file and above logic not executed.
654
+ #2) Valid oci_la_log_set_key + No oci_la_log_set_ext_regex
655
+ #a) Valid key available in record with oci_la_log_set_key corresponding value (oci_la_log_set_key is a key in config file) --> oci_la_log_set
656
+ #b) No Valid key available in record with oci_la_log_set_key corresponding value --> nil
657
+ #3) Valid key available in record with oci_la_log_set_key corresponding value + Valid oci_la_log_set_ext_regex
658
+ #a) Parse success --> parsed oci_la_log_set
659
+ #b) Parse failure --> nil (as oci_la_log_set value)
660
+ #4) No oci_la_log_set_key --> do nothing --> nil
661
+
662
+ #Extracting oci_la_log_set when oci_la_log_set and oci_la_log_set_ext_regex is provided.
663
+ #1) Valid oci_la_log_set + No oci_la_log_set_ext_regex --> oci_la_log_set
664
+ #2) Valid oci_la_log_set + Valid oci_la_log_set_ext_regex
665
+ #a) Parse success --> parsed oci_la_log_set
666
+ #b) Parse failure --> nil (as oci_la_log_set value)
667
+ #3) No oci_la_log_set --> do nothing --> nil
668
+
669
+ unparsed_logSet = nil
670
+ processed_logSet = nil
671
+ if is_tag_exists && tag_logSet_map.has_key?(record["tag"])
672
+ record["oci_la_log_set"] = tag_logSet_map[record["tag"]]
673
+ else
674
+ if record_hash.has_key?("oci_la_log_set_key")
675
+ if is_valid(record["oci_la_log_set_key"]) && record_hash.has_key?(record["oci_la_log_set_key"])
676
+ if is_valid(record[record["oci_la_log_set_key"]])
677
+ unparsed_logSet = record[record["oci_la_log_set_key"]]
678
+ processed_logSet = get_or_parse_logSet(unparsed_logSet,record, record_hash,is_tag_exists)
679
+ end
608
680
  end
609
681
  end
610
- end
611
- if !is_valid(processed_logSet) && record_hash.has_key?("oci_la_log_set")
612
- if is_valid(record["oci_la_log_set"])
613
- unparsed_logSet = record["oci_la_log_set"]
614
- processed_logSet = get_or_parse_logSet(unparsed_logSet,record, record_hash,is_tag_exists)
682
+ if !is_valid(processed_logSet) && record_hash.has_key?("oci_la_log_set")
683
+ if is_valid(record["oci_la_log_set"])
684
+ unparsed_logSet = record["oci_la_log_set"]
685
+ processed_logSet = get_or_parse_logSet(unparsed_logSet,record, record_hash,is_tag_exists)
686
+ end
615
687
  end
616
- end
617
- record["oci_la_log_set"] = processed_logSet
618
- tag_logSet_map[record["tag"]] = processed_logSet
619
- end
688
+ record["oci_la_log_set"] = processed_logSet
689
+ tag_logSet_map[record["tag"]] = processed_logSet
690
+ end
691
+ is_valid, metricsLabels.invalid_reason = is_valid_record(record_hash,record)
620
692
 
621
- unless is_valid_record(record_hash,record)
622
- if is_tag_exists
623
- invalid_tag_set.add(record["tag"])
624
- invalid_records_per_tag[record["tag"]] = 1
625
- end
626
- next
627
- end
628
- #This will check for null or empty messages and only that record will be ignored.
629
- if !is_valid(record["message"])
630
- if is_tag_exists
631
- @@logger.warn {"'message' field has empty value, Skipping records associated with tag : #{record["tag"]}."}
632
- if invalid_records_per_tag.has_key?(record["tag"])
633
- invalid_records_per_tag[record["tag"]] += 1
634
- else
693
+ unless is_valid
694
+ if is_tag_exists
695
+ invalid_tag_set.add(record["tag"])
635
696
  invalid_records_per_tag[record["tag"]] = 1
636
697
  end
698
+ next
699
+ end
700
+ metricsLabels.logGroupId = record["oci_la_log_group_id"]
701
+ metricsLabels.logSourceName = record["oci_la_log_source_name"]
702
+ if record["oci_la_log_set"] != nil
703
+ metricsLabels.logSet = record["oci_la_log_set"]
704
+ end
705
+ #This will check for null or empty messages and only that record will be ignored.
706
+ if !is_valid(record["message"])
707
+ metricsLabels.invalid_reason = OutOracleOCILogAnalytics::METRICS_INVALID_REASON_MESSAGE
708
+ if is_tag_exists
709
+ @@logger.warn {"'message' field has empty value, Skipping records associated with tag : #{record["tag"]}."}
710
+ if invalid_records_per_tag.has_key?(record["tag"])
711
+ invalid_records_per_tag[record["tag"]] += 1
712
+ else
713
+ invalid_records_per_tag[record["tag"]] = 1
714
+ end
715
+ else
716
+ @@logger.warn {"'message' field has empty value, Skipping record."}
717
+ end
718
+ next
637
719
  else
638
- @@logger.warn {"'message' field has empty value, Skipping record."}
720
+ record["message"] = json_message_handler(record["message"])
639
721
  end
640
- next
641
- else
642
- record["message"] = json_message_handler(record["message"])
643
- end
644
722
 
645
- if record_hash.has_key?("kubernetes")
646
- record["oci_la_metadata"] = get_kubernetes_metadata(record["oci_la_metadata"],record)
647
- end
723
+ if record_hash.has_key?("kubernetes")
724
+ record["oci_la_metadata"] = get_kubernetes_metadata(record["oci_la_metadata"],record)
725
+ end
648
726
 
649
- if tag_metadata_map.has_key?(record["tag"])
650
- record["oci_la_metadata"] = tag_metadata_map[record["tag"]]
651
- else
652
- if record_hash.has_key?("oci_la_metadata")
653
- record["oci_la_metadata"] = get_valid_metadata(record["oci_la_metadata"])
654
- tags_per_logGroupId[record["tag"]] = record["oci_la_metadata"]
655
- else
656
- tags_per_logGroupId[record["tag"]] = nil
657
- end
658
- end
727
+ if tag_metadata_map.has_key?(record["tag"])
728
+ record["oci_la_metadata"] = tag_metadata_map[record["tag"]]
729
+ else
730
+ if record_hash.has_key?("oci_la_metadata")
731
+ record["oci_la_metadata"] = get_valid_metadata(record["oci_la_metadata"])
732
+ tags_per_logGroupId[record["tag"]] = record["oci_la_metadata"]
733
+ else
734
+ tags_per_logGroupId[record["tag"]] = nil
735
+ end
736
+ end
659
737
 
660
- if is_tag_exists
661
- if tags_per_logGroupId.has_key?(record["oci_la_log_group_id"])
662
- if !tags_per_logGroupId[record["oci_la_log_group_id"]].include?(record["tag"])
663
- tags_per_logGroupId[record["oci_la_log_group_id"]] += ", "+record["tag"]
738
+ if is_tag_exists
739
+ if tags_per_logGroupId.has_key?(record["oci_la_log_group_id"])
740
+ if !tags_per_logGroupId[record["oci_la_log_group_id"]].include?(record["tag"])
741
+ tags_per_logGroupId[record["oci_la_log_group_id"]] += ", "+record["tag"]
742
+ end
743
+ else
744
+ tags_per_logGroupId[record["oci_la_log_group_id"]] = record["tag"]
745
+ end
664
746
  end
665
- else
666
- tags_per_logGroupId[record["oci_la_log_group_id"]] = record["tag"]
667
- end
668
- end
669
747
 
670
- records << record
748
+ records << record
749
+ ensure
750
+ # To get chunk_time_to_receive metrics per tag, corresponding latency and total records are calculated
751
+ if tag_metrics_set.has_key?(record["tag"])
752
+ metricsLabels = tag_metrics_set[record["tag"]]
753
+ latency = metricsLabels.latency
754
+ records_per_tag = metricsLabels.records_per_tag
755
+ else
756
+ latency = 0
757
+ records_per_tag = 0
758
+ end
759
+ latency += (current_f - time)
760
+ records_per_tag += 1
761
+ metricsLabels.latency = latency
762
+ metricsLabels.records_per_tag = records_per_tag
763
+ tag_metrics_set[record["tag"]] = metricsLabels
764
+ if record["oci_la_log_group_id"] != nil && !logGroup_labels_set.has_key?(record["oci_la_log_group_id"])
765
+ logGroup_labels_set[record["oci_la_log_group_id"]] = metricsLabels
766
+ end
767
+ end
671
768
  else
672
769
  @@logger.trace {"Record is nil, ignoring the record"}
673
770
  end
674
771
  end
675
772
  @@logger.debug {"records.length:#{records.length}"}
773
+
774
+ tag_metrics_set.each do |tag,metricsLabels|
775
+ latency_avg = (metricsLabels.latency / metricsLabels.records_per_tag).round(3)
776
+ @@prometheusMetrics.chunk_time_to_receive.observe(latency_avg, labels: { tag: tag})
777
+ end
778
+
676
779
  lrpes_for_logGroupId = {}
677
780
  records.group_by{|record|
678
781
  oci_la_log_group_id = record['oci_la_log_group_id']
@@ -683,29 +786,62 @@ module Fluent::Plugin
683
786
  rescue => ex
684
787
  @@logger.error {"Error occurred while grouping records by oci_la_log_group_id:#{ex.inspect}"}
685
788
  end
686
- return incoming_records_per_tag,invalid_records_per_tag,tags_per_logGroupId,lrpes_for_logGroupId
789
+ return incoming_records_per_tag,invalid_records_per_tag,tag_metrics_set,logGroup_labels_set,tags_per_logGroupId,lrpes_for_logGroupId
687
790
  end
688
791
  # main entry point for FluentD's flush_threads, which get invoked
689
792
  # when a chunk is ready for flushing (see chunk limits and flush_intervals)
690
793
  def write(chunk)
691
794
  @@logger.info {"Received new chunk, started processing ..."}
692
- metrics = Hash.new
693
- metrics["count"] = 0
694
- metrics["event"] = "zipping"
695
- metrics["bytes_in"] = chunk.bytesize
696
- metrics['records_dropped'] = 0
795
+ #@@prometheusMetrics.bytes_received.set(chunk.bytesize, labels: { tag: nil})
697
796
  begin
698
797
  # 1) Create an in-memory zipfile for the given FluentD chunk
699
798
  # 2) Synchronization has been removed. See EMCLAS-28675
700
799
 
701
800
  begin
702
801
  lrpes_for_logGroupId = {}
703
- incoming_records_per_tag,invalid_records_per_tag,tags_per_logGroupId,lrpes_for_logGroupId = group_by_logGroupId(chunk)
802
+ incoming_records_per_tag,invalid_records_per_tag,tag_metrics_set,logGroup_labels_set,tags_per_logGroupId,lrpes_for_logGroupId = group_by_logGroupId(chunk)
704
803
  valid_message_per_tag = Hash.new
804
+ logGroup_metrics_map = Hash.new
805
+ metricsLabels_array = []
806
+
705
807
  incoming_records_per_tag.each do |key,value|
706
808
  dropped_messages = (invalid_records_per_tag.has_key?(key)) ? invalid_records_per_tag[key].to_i : 0
707
809
  valid_messages = value.to_i - dropped_messages
708
810
  valid_message_per_tag[key] = valid_messages
811
+
812
+ metricsLabels = tag_metrics_set[key]
813
+ if metricsLabels == nil
814
+ metricsLabels = MetricsLabels.new
815
+ end
816
+ metricsLabels.records_valid = valid_messages
817
+ # logGroup_metrics_map will have logGroupId as key and metricsLabels_array as value.
818
+ # In a chunk we can have different logGroupIds but we are creating payloads based on logGroupId and that can internally have different logSourceName and tag data.
819
+ # Using logGroup_metrics_map, for a given chunk, we can produce the metrics with proper logGroupId and its corresponding values.
820
+ if metricsLabels.logGroupId != nil
821
+ if logGroup_metrics_map.has_key?(metricsLabels.logGroupId)
822
+ metricsLabels_array = logGroup_metrics_map[metricsLabels.logGroupId]
823
+ else
824
+ metricsLabels_array = []
825
+ end
826
+ metricsLabels_array.push(metricsLabels)
827
+ logGroup_metrics_map[metricsLabels.logGroupId] = metricsLabels_array
828
+ end
829
+
830
+ @@prometheusMetrics.records_received.set(value.to_i, labels: { tag: key,
831
+ oci_la_log_group_id: metricsLabels.logGroupId,
832
+ oci_la_log_source_name: metricsLabels.logSourceName,
833
+ oci_la_log_set: metricsLabels.logSet})
834
+
835
+ @@prometheusMetrics.records_invalid.set(dropped_messages, labels: { tag: key,
836
+ oci_la_log_group_id: metricsLabels.logGroupId,
837
+ oci_la_log_source_name: metricsLabels.logSourceName,
838
+ oci_la_log_set: metricsLabels.logSet,
839
+ reason: metricsLabels.invalid_reason})
840
+ @@prometheusMetrics.records_valid.set(valid_messages, labels: { tag: key,
841
+ oci_la_log_group_id: metricsLabels.logGroupId,
842
+ oci_la_log_source_name: metricsLabels.logSourceName,
843
+ oci_la_log_set: metricsLabels.logSet})
844
+
709
845
  if dropped_messages > 0
710
846
  @@logger.info {"Messages: #{value.to_i} \t Valid: #{valid_messages} \t Invalid: #{dropped_messages} \t tag:#{key}"}
711
847
  end
@@ -720,17 +856,27 @@ module Fluent::Plugin
720
856
  zippedstream = nil
721
857
  oci_la_log_set = nil
722
858
  logSets_per_logGroupId_map = Hash.new
859
+
860
+ metricsLabels_array = logGroup_metrics_map[oci_la_log_group_id]
861
+
723
862
  # Only MAX_FILES_PER_ZIP (100) files are allowed, which will be grouped and zipped.
724
863
  # Due to MAX_FILES_PER_ZIP constraint, for a oci_la_log_group_id, we can get more than one zip file and those many api calls will be made.
725
864
  logSets_per_logGroupId_map, oci_la_global_metadata = get_logSets_map_per_logGroupId(oci_la_log_group_id,records_per_logGroupId)
726
865
  if logSets_per_logGroupId_map != nil
727
- logSets_per_logGroupId_map.each do |file_count,records_per_logSet_map|
728
- zippedstream,number_of_records = get_zipped_stream(oci_la_log_group_id,oci_la_global_metadata,records_per_logSet_map)
729
- if zippedstream != nil
730
- zippedstream.rewind #reposition buffer pointer to the beginning
731
- upload_to_oci(oci_la_log_group_id, number_of_records, zippedstream)
732
- end
733
- end
866
+ bytes_out = 0
867
+ records_out = 0
868
+ chunk_upload_time_taken = nil
869
+ chunk_upload_time_taken = Benchmark.measure {
870
+ logSets_per_logGroupId_map.each do |file_count,records_per_logSet_map|
871
+ zippedstream,number_of_records = get_zipped_stream(oci_la_log_group_id,oci_la_global_metadata,records_per_logSet_map)
872
+ if zippedstream != nil
873
+ zippedstream.rewind #reposition buffer pointer to the beginning
874
+ upload_to_oci(oci_la_log_group_id, number_of_records, zippedstream, metricsLabels_array)
875
+ end
876
+ end
877
+ }.real.round(3)
878
+ @@prometheusMetrics.chunk_time_to_upload.observe(chunk_upload_time_taken, labels: { oci_la_log_group_id: oci_la_log_group_id})
879
+
734
880
  end
735
881
  ensure
736
882
  zippedstream&.close
@@ -844,8 +990,10 @@ module Fluent::Plugin
844
990
  end
845
991
 
846
992
  # upload zipped stream to oci
847
- def upload_to_oci(oci_la_log_group_id, number_of_records, zippedstream)
993
+ def upload_to_oci(oci_la_log_group_id, number_of_records, zippedstream, metricsLabels_array)
848
994
  begin
995
+ error_reason = nil
996
+ error_code = nil
849
997
  opts = {payload_type: "ZIP"}
850
998
 
851
999
  response = @@loganalytics_client.upload_log_events_file(namespace_name=@namespace,
@@ -854,6 +1002,19 @@ module Fluent::Plugin
854
1002
  opts)
855
1003
  if !response.nil? && response.status == 200 then
856
1004
  headers = response.headers
1005
+
1006
+ metricsLabels_array.each { |metricsLabels|
1007
+ @@prometheusMetrics.records_posted.set(metricsLabels.records_valid, labels: { tag: metricsLabels.tag,
1008
+ oci_la_log_group_id: metricsLabels.logGroupId,
1009
+ oci_la_log_source_name: metricsLabels.logSourceName,
1010
+ oci_la_log_set: metricsLabels.logSet})
1011
+ }
1012
+
1013
+ #zippedstream.rewind #reposition buffer pointer to the beginning
1014
+ #zipfile = zippedstream&.sysread&.dup
1015
+ #bytes_out = zipfile&.length
1016
+ #@@prometheusMetrics.bytes_posted.set(bytes_out, labels: { oci_la_log_group_id: oci_la_log_group_id})
1017
+
857
1018
  @@logger.info {"The payload has been successfully uploaded to logAnalytics -
858
1019
  oci_la_log_group_id: #{oci_la_log_group_id},
859
1020
  ConsumedRecords: #{number_of_records},
@@ -863,13 +1024,16 @@ module Fluent::Plugin
863
1024
  opc-object-id: #{headers['opc-object-id']}"}
864
1025
  end
865
1026
  rescue OCI::Errors::ServiceError => serviceError
1027
+ error_code = serviceError.status_code
866
1028
  case serviceError.status_code
867
1029
  when 400
1030
+ error_reason = OutOracleOCILogAnalytics::METRICS_SERVICE_ERROR_REASON_400
868
1031
  @@logger.error {"oci upload exception : Error while uploading the payload. Invalid/Incorrect/missing Parameter - opc-request-id:#{serviceError.request_id}"}
869
1032
  if plugin_retry_on_4xx
870
1033
  raise serviceError
871
1034
  end
872
1035
  when 401
1036
+ error_reason = OutOracleOCILogAnalytics::METRICS_SERVICE_ERROR_REASON_401
873
1037
  @@logger.error {"oci upload exception : Error while uploading the payload. Not Authenticated.
874
1038
  opc-request-id:#{serviceError.request_id}
875
1039
  message: #{serviceError.message}"}
@@ -877,6 +1041,7 @@ module Fluent::Plugin
877
1041
  raise serviceError
878
1042
  end
879
1043
  when 404
1044
+ error_reason = OutOracleOCILogAnalytics::METRICS_SERVICE_ERROR_REASON_404
880
1045
  @@logger.error {"oci upload exception : Error while uploading the payload. Authorization failed for given oci_la_log_group_id against given Tenancy Namespace.
881
1046
  oci_la_log_group_id: #{oci_la_log_group_id}
882
1047
  Namespace: #{@namespace}
@@ -886,34 +1051,53 @@ module Fluent::Plugin
886
1051
  raise serviceError
887
1052
  end
888
1053
  when 429
1054
+ error_reason = OutOracleOCILogAnalytics::METRICS_SERVICE_ERROR_REASON_429
889
1055
  @@logger.error {"oci upload exception : Error while uploading the payload. Too Many Requests - opc-request-id:#{serviceError.request_id}"}
890
1056
  raise serviceError
891
1057
  when 500
1058
+ error_reason = OutOracleOCILogAnalytics::METRICS_SERVICE_ERROR_REASON_500
892
1059
  @@logger.error {"oci upload exception : Error while uploading the payload. Internal Server Error - opc-request-id:#{serviceError.request_id}"}
893
1060
  raise serviceError
894
1061
 
895
1062
  when 502
1063
+ error_reason = OutOracleOCILogAnalytics::METRICS_SERVICE_ERROR_REASON_502
896
1064
  @@logger.error {"oci upload exception : Error while uploading the payload. Bad Gateway - opc-request-id:#{serviceError.request_id}"}
897
1065
  raise serviceError
898
1066
 
899
1067
  when 503
1068
+ error_reason = OutOracleOCILogAnalytics::METRICS_SERVICE_ERROR_REASON_503
900
1069
  @@logger.error {"oci upload exception : Error while uploading the payload. Service unavailable - opc-request-id:#{serviceError.request_id}"}
901
1070
  raise serviceError
902
1071
 
903
1072
  when 504
1073
+ error_reason = OutOracleOCILogAnalytics::METRICS_SERVICE_ERROR_REASON_504
904
1074
  @@logger.error {"oci upload exception : Error while uploading the payload. Gateway Timeout - opc-request-id:#{serviceError.request_id}"}
905
1075
  raise serviceError
906
1076
 
907
1077
  when 505
1078
+ error_reason = OutOracleOCILogAnalytics::METRICS_SERVICE_ERROR_REASON_505
908
1079
  @@logger.error {"oci upload exception : Error while uploading the payload. HTTP Version Not Supported - opc-request-id:#{serviceError.request_id}"}
909
1080
  raise serviceError
910
1081
  else
1082
+ error_reason = OutOracleOCILogAnalytics::METRICS_SERVICE_ERROR_REASON_UNKNOWN
911
1083
  @@logger.error {"oci upload exception : Error while uploading the payload #{serviceError.message}"}
912
1084
  raise serviceError
913
1085
  end
914
1086
  rescue => ex
1087
+ error_reason = ex
915
1088
  @@logger.error {"oci upload exception : Error while uploading the payload. #{ex}"}
1089
+ ensure
1090
+ if error_reason != nil
1091
+ metricsLabels_array.each { |metricsLabels|
1092
+ @@prometheusMetrics.records_error.set(metricsLabels.records_valid, labels: { tag: metricsLabels.tag,
1093
+ oci_la_log_group_id: metricsLabels.logGroupId,
1094
+ oci_la_log_source_name: metricsLabels.logSourceName,
1095
+ oci_la_log_set: metricsLabels.logSet,
1096
+ error_code: error_code,
1097
+ reason: error_reason})
1098
+ }
1099
+ end
916
1100
  end
917
1101
  end
918
1102
  end
919
- end
1103
+ end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-oci-logging-analytics
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.4
5
5
  platform: ruby
6
6
  authors:
7
- - OCI Logging Analytics Team
7
+ - Oracle
8
+ - 'OCI Observability: Logging Analytics'
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2022-01-14 00:00:00.000000000 Z
12
+ date: 2022-06-20 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rake
@@ -78,17 +79,32 @@ dependencies:
78
79
  requirements:
79
80
  - - "~>"
80
81
  - !ruby/object:Gem::Version
81
- version: '2.13'
82
+ version: '2.16'
82
83
  type: :runtime
83
84
  prerelease: false
84
85
  version_requirements: !ruby/object:Gem::Requirement
85
86
  requirements:
86
87
  - - "~>"
87
88
  - !ruby/object:Gem::Version
88
- version: '2.13'
89
- description: Fluentd Output plugin to ship logs/events to OCI Logging Analytics.
89
+ version: '2.16'
90
+ - !ruby/object:Gem::Dependency
91
+ name: prometheus-client
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 4.0.0
97
+ type: :runtime
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 4.0.0
104
+ description: OCI Logging Analytics Fluentd output plugin for ingesting the collected
105
+ log events to OCI Logging Analytics.
90
106
  email:
91
- - oci_la_plugins@oracle.com
107
+ - oci_la_plugins_grp@oracle.com
92
108
  executables: []
93
109
  extensions: []
94
110
  extra_rdoc_files: []
@@ -101,7 +117,10 @@ files:
101
117
  homepage:
102
118
  licenses:
103
119
  - UPL-1.0
104
- metadata: {}
120
+ metadata:
121
+ documentation_uri: https://docs.oracle.com/en/learn/oci_logging_analytics_fluentd/
122
+ source_code_uri: https://github.com/oracle-quickstart/oci-logan-fluentd-output-plugin
123
+ changelog_uri: https://github.com/oracle-quickstart/oci-logan-fluentd-output-plugin/blob/main/CHANGELOG.md
105
124
  post_install_message:
106
125
  rdoc_options: []
107
126
  require_paths:
@@ -110,15 +129,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
129
  requirements:
111
130
  - - ">="
112
131
  - !ruby/object:Gem::Version
113
- version: '0'
132
+ version: 2.6.0
114
133
  required_rubygems_version: !ruby/object:Gem::Requirement
115
134
  requirements:
116
135
  - - ">="
117
136
  - !ruby/object:Gem::Version
118
137
  version: '0'
119
138
  requirements: []
120
- rubygems_version: 3.0.8
139
+ rubyforge_project:
140
+ rubygems_version: 2.6.13
121
141
  signing_key:
122
142
  specification_version: 4
123
- summary: Fluentd Output plugin to ship logs/events to OCI Logging Analytics.
143
+ summary: Fluentd output plugin for OCI Logging Analytics.
124
144
  test_files: []