BrunoBonacci / mulog

μ/log is a micro-logging library that logs events and data, not words!
https://cljdoc.org/d/com.brunobonacci/mulog/
Apache License 2.0
478 stars 47 forks source link

CloudWatch Publisher: error when transform function returns no events #125

Open MastroCiccio opened 2 weeks ago

MastroCiccio commented 2 weeks ago

Hi, I noticed the CloudWatch publisher to generate an error event whenever the transform function returns the empty sequence since the AWS API PutLogEvents does not accept the empty array as the input.

Here the details of the error from the mulog event:

{:publisher-type   :cloudwatch,
 :publisher-id     "4xdL2TzAC-JxUQldM0ZhQtavsek67jsa",
 :mulog/namespace  "clojure.core",
 :mulog/action     :publish,
 :mulog/timestamp  1718780832832,
 :mulog/origin     :mulog/core,
 :mulog/trace-id   #mulog/flake "4xdL2tisnXGbnpUNPIerAvVG4Yt_DBh-",
 :mulog/event-name :mulog/publisher-error,
 :exception        #error {:cause "μ/log cloudwatch publisher publish failure, group 'dev-log' stream '4xdL2SoPQ1pBbbsx2Gx7TZCZnlg53jc0' reason: 1 validation error detected: Value '[]' at 'logEvents' failed to satisfy constraint: Member must have length greater than or equal to 1 "
                           :data  {:rs          {:__type                       "InvalidParameterException",
                                                 :message                      "1 validation error detected: Value '[]' at 'logEvents' failed to satisfy constraint: Member must have length greater than or equal to 1",
                                                 :cognitect.aws.http/status    400,
                                                 :cognitect.anomalies/category :cognitect.anomalies/incorrect,
                                                 :cognitect.aws.error/code     "InvalidParameterException"},
                                   :group-name  "dev-log",
                                   :stream-name "4xdL2SoPQ1pBbbsx2Gx7TZCZnlg53jc0"}
                           :via   [{:type clojure.lang.ExceptionInfo
                                    :message "μ/log cloudwatch publisher publish failure, group 'dev-log' stream '4xdL2SoPQ1pBbbsx2Gx7TZCZnlg53jc0' reason: 1 validation error detected: Value '[]' at 'logEvents' failed to satisfy constraint: Member must have length greater than or equal to 1 "
                                    :data {:rs          {:__type                       "InvalidParameterException",
                                                         :message                      "1 validation error detected: Value '[]' at 'logEvents' failed to satisfy constraint: Member must have length greater than or equal to 1",
                                                         :cognitect.aws.http/status    400,
                                                         :cognitect.anomalies/category :cognitect.anomalies/incorrect,
                                                         :cognitect.aws.error/code     "InvalidParameterException"},
                                           :group-name  "dev-log",
                                           :stream-name "4xdL2SoPQ1pBbbsx2Gx7TZCZnlg53jc0"}
                                    :at [com.brunobonacci.mulog.publishers.cloudwatch$publish_BANG_ invokeStatic "cloudwatch.clj" 58]}]
                           :trace [[com.brunobonacci.mulog.publishers.cloudwatch$publish_BANG_ invokeStatic "cloudwatch.clj" 58]
                                   [com.brunobonacci.mulog.publishers.cloudwatch$publish_BANG_ invoke "cloudwatch.clj" 43]
                                   [com.brunobonacci.mulog.publishers.cloudwatch$put_log_events invokeStatic "cloudwatch.clj" 76]
                                   [com.brunobonacci.mulog.publishers.cloudwatch$put_log_events invoke "cloudwatch.clj" 70]
                                   [com.brunobonacci.mulog.publishers.cloudwatch.CloudwatchPublisher publish "cloudwatch.clj" 103]
                                   [com.brunobonacci.mulog.core$start_publisher_BANG_$publish_attempt__8976 invoke "core.clj" 194]
                                   [clojure.core$binding_conveyor_fn$fn__5823 invoke "core.clj" 2050]
                                   [clojure.lang.AFn applyToHelper "AFn.java" 154]
                                   [clojure.lang.RestFn applyTo "RestFn.java" 132]
                                   [clojure.lang.Agent$Action doRun "Agent.java" 114]
                                   [clojure.lang.Agent$Action run "Agent.java" 163]
                                   [java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1136]
                                   [java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 635]
                                   [java.lang.Thread run "Thread.java" 840]]}}

Here a possible implementation to replicate the scenario:

(require '[[com.brunobonacci.mulog :as ml])
(ml/start-publisher! {:type :console :pretty? true})
(ml/start-publisher! {:type :cloudwatch :group-name "dev-log" :transform (partial filter (comp :test-event :mulog/event-name))})
(ml/log :test-event)

Is this a desired behavior? I'm implementing a solution with different publishers: since the CloudWatch publisher matches only a specific set of events, it wouldn't be unusual for the transform function to return the empty seq, thus generating the error event catched by the other publishers. For now I'm filtering out this specific error from the other publishers, but it's kind of annoying...

Thanks for the help

BrunoBonacci commented 2 weeks ago

It looks like a bug to me. I'll fix it in the next release.

MastroCiccio commented 2 weeks ago

Thank you!