-
Notifications
You must be signed in to change notification settings - Fork 181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
W-11984725-logger-revamp-duke #2402
base: v4.4
Are you sure you want to change the base?
Changes from all commits
e5e634c
6b0188e
8c896f1
7086991
cc63bf0
788f7c8
1c1f03e
35492b7
ac632d1
447c0e3
48d4009
e8a51f5
0e2636b
f57a925
aca0430
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,76 +4,222 @@ include::_attributes.adoc[] | |
endif::[] | ||
:keywords: mule, esb, studio, logger, logs, log, notifications, errors, debug | ||
|
||
This Core component helps you monitor and debug your Mule application by logging important information such as error messages, status notifications, payloads, and so on. You can add a Logger anywhere in a flow, and you can configure it to log a string that you specify, the output of a DataWeave expression you write, or any combination of strings and expressions. | ||
Logs help you monitor and debug your Mule applications by printing important information such as error messages, status notifications, payload data, and so on. The Logger component (`<logger/>`) provides a way to add custom log messages to the logs. You can configure any number of Logger components in a flow with a string, a DataWeave expression, or any combination of strings and expressions. | ||
|
||
[WARNING] | ||
-- | ||
Keep in mind that the Logger is one of the only components that supports mixing Strings and expressions within a value. DataWeave String interpolation or concatenation within a single expression should be used elsewhere. | ||
-- | ||
Mule applications print logs in several locations. In Anypoint Studio, the logs print to the xref:studio::index.adoc#console[console]. For information about application logs in a production environment, see xref:logging-in-mule.adoc#app_logs[App Logs]. | ||
|
||
The configured messages are logged to the app's log file, which is located in `MULE_HOME/logs/<app-name>.log` if no custom log file path is specified in the `log4j2.xml` file. + | ||
In Studio, the logs show in the Console. | ||
|
||
The following example displays the message in Set Payload in a browser and also logs the message. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. removed bc "... in a browser": it's in the browser bc of the request to the listener, not directly relevant to logger |
||
The following example logs the message `Hello MuleSoft!` at the default log level, `INFO`: | ||
|
||
image::logger-flow.png[] | ||
|
||
.Example: XML Configuration of the Flow | ||
[source,xml,linenums] | ||
---- | ||
<http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8081"/> | ||
<flow name="logger-example-Flow"> | ||
<http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" > | ||
<http:listener-connection host="0.0.0.0" port="8081" /> | ||
</http:listener-config><flow name="logger-example-Flow"> | ||
<http:listener config-ref="HTTP_Listener_Configuration" path="/"/> | ||
<set-payload value="Hello MuleSoft!"/> | ||
<logger message="#[payload]" level="INFO"/> | ||
</flow> | ||
---- | ||
|
||
== Logger Configuration | ||
In the Studio console, the logged message, `Hello MuleSoft!` looks like this: | ||
|
||
[source,logs] | ||
---- | ||
INFO 2022-11-10 19:39:18,222 [[MuleRuntime].uber.01: [w-logger].logger-example-Flow.CPU_LITE @6f862394] | ||
[processor: logger-example-Flow/processors/1; event: 6bd2b350-6172-11ed-9f87-147ddaaf4f97] | ||
org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Hello MuleSoft! | ||
---- | ||
|
||
* The configurable log level is `INFO`. See <<reference>>. | ||
* A date-time stamp `2022-11-10 19:39:18,222` marks an execution of a Logger. | ||
* CPU_LITE is the See xref:execution-engine.adoc#processing_types[processing type]. | ||
* `event: 6bd2b350-6172-11ed-9f87-147ddaaf4f97` identifies the Mule event to which the logged message applies. | ||
* The message `LoggerMessageProcessor` processor prints the message `Hello MuleSoft!`. | ||
|
||
[[reference]] | ||
== Reference | ||
|
||
The Logger provides configurable properties for the name of the logger, the message to log, the log level, and a string you can use to name or categorize a type of log message. | ||
|
||
image::logger.png[] | ||
|
||
[%header%autowidth.spread,cols="a,a,a,a"] | ||
[%header%autowidth.spread,cols="1a,1a,4a"] | ||
|=== | ||
| Field | Value | Description | Example | ||
| Field | Attribute | Description | ||
|
||
| Message | String or DataWeave expression | Specifies the Mule log message. By default, messages are logged to the application's log file. | | ||
`message="Current payload is #[payload]"` | ||
| *Message* | `message` | String or DataWeave expression that specifies the Mule log message. By default, messages log to the application's log file and in the console where the application runs, such as the Anypoint Studio console or the OS console for on-premises deployments. Example: | ||
`message="Current payload is \#[payload]"`. Note that the Logger is one of the only components that supports this syntax to embed an expression (such as `#[payload]` within a string. Messages in other Mule components require string interpolation or concatenation within a single DataWeave expression. | ||
|
||
| Level | | ||
Available options: | ||
| Level | `level` | Specifies a log level. `INFO` is the default. Available options: | ||
|
||
* `DEBUG` | ||
* `ERROR` | ||
* `INFO`(Default) | ||
* `INFO` | ||
* `TRACE` | ||
* `WARN` | | ||
Specifies the log level. | ||
|
||
| | ||
`level="ERROR"` | ||
* `WARN` | ||
|
||
| Category | String | Optional setting that specifies a category name that it adds to `log4j2.xml` file. For example, you might use a category to route your log messages based on your category, or you might set log levels based on category. | | ||
`category="MyCustomCategory"` | ||
Example: `level="ERROR"` | ||
|
||
| Category | `category` | Optional string that specifies a category name that it adds to `log4j2.xml` file. For example, you might use a category to route your log messages based on your category, or you might set log levels based on category. Example: | ||
`category="MyCustomCategory"`. | ||
|=== | ||
|
||
== Examples | ||
|
||
This Logger is set to monitor message processing status, mixing Strings and expressions: | ||
The following example you specifies a category `category="MyCustomCategory"` with the `message="My Message"`: | ||
|
||
[source,xml,linenums] | ||
[source,xml] | ||
---- | ||
<logger level="INFO" doc:name="Logger" | ||
message='#["My Message"]' category="MyCustomCategory"/> | ||
---- | ||
|
||
Notice that the category `MyCustomCategory` replaces the full package name of the processor, `org.mule.runtime.core.internal.processor.LoggerMessageProcessor`, for example: | ||
|
||
[source,logs] | ||
---- | ||
INFO 2022-11-11 15:17:53,138 [[MuleRuntime].uber.04: | ||
[w-logger].logger-example-Flow.CPU_LITE @7ea85211] | ||
[processor: logger-example-Flow/processors/1; | ||
event: 113d6700-6217-11ed-86de-147ddaaf4f97] | ||
MyCustomCategory: My Message | ||
---- | ||
|
||
The following example places a DataWeave selector expression within a `message` string: | ||
|
||
[source,xml] | ||
---- | ||
<logger category="monitoring" message="Message #[payload.id] processed successfully" level="INFO"/> | ||
---- | ||
|
||
This Logger set to record the processing time of a flow, using a single expression and DataWeave's String concatenation: | ||
Assuming a payload such as `{"id" : "100", "some-key" : "some value" }`, the Logger prints the message `Message 100 processed successfully`, for example: | ||
|
||
[source,xml,linenums] | ||
[source,xml] | ||
---- | ||
INFO 2022-11-10 21:11:07,791 [[MuleRuntime].uber.09: | ||
[w-logger].logger-example-Flow.CPU_LITE @600dcddb] | ||
[processor: logger-example-Flow/processors/1; | ||
event: 3fd13710-617f-11ed-900f-147ddaaf4f97] | ||
org.mule.runtime.core.internal.processor.LoggerMessageProcessor: | ||
Message 100 processed successfully | ||
---- | ||
|
||
This Logger records the processing time of a flow, using a single expression and DataWeave concatenation: | ||
|
||
//TODO: Need to show how to get processing time or use a better example that doesn't throw an error. | ||
[source,xml] | ||
---- | ||
<logger category="performance" message="#['Message ' ++ payload.id ++ ' took ' ++ vars.processingTime ++ ' milliseconds to process']" level="INFO"/> | ||
<logger category="performance" message="#['Message ' ++ payload.id ++ ' took ' ++ vars.processingTime ++ ' milliseconds to process']" level="INFO"/> | ||
---- | ||
|
||
== See also | ||
[[non_repeatable_streams]] | ||
== Non-Repeatable Streams | ||
|
||
In Mule, a non-repeatable stream can be read only once. The Logger consumes a payload that is streamed in a non-repeatable way and does not pass it to the next component in the flow. In the next component, the `payload` selector returns a `null` or empty value. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When Logger reads a value that's a non-repeatable stream, that value is consumed. Logger itself doesn't return anything (void). Transform Message is mutating the payload. Reads and applies a transformation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Output of Logger is void. |
||
|
||
|
||
This scenario can occur if a Mule component, such as as a xref:file-connector::file-documentation.adoc#write[File Write operation] or the xref:batch-reference.adoc#ref_batch_aggregator_component[Batch Aggregator] component, is configured with a _non-repeatable_ streaming strategy (see xref:tuning-repeatable-nonrepeatable.adoc[]). | ||
|
||
|
||
[[example_non_repeatable_stream]] | ||
To illustrate this scenario, assume a Batch Aggregator that contains two Logger components is set to stream (`stream`) it input, the array `[1,2]`: | ||
dukesphere marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
[source,xml] | ||
---- | ||
<flow name="streaming-to-logger-ex" > | ||
<scheduler doc:name="Scheduler" > | ||
<scheduling-strategy > | ||
<fixed-frequency frequency="30" timeUnit="SECONDS"/> | ||
</scheduling-strategy> | ||
</scheduler> | ||
<set-payload value="#[[1,2]]" doc:name="Set Payload" /> | ||
<batch:job jobName="Batch_Job"> | ||
<batch:process-records > | ||
<batch:step name="Batch_Step" > | ||
<batch:aggregator doc:name="Batch Aggregator" | ||
streaming="true"> | ||
<!-- First Logger --> | ||
<logger level="INFO" doc:name="Logger 1" | ||
category="AGGREGATOR: FIRST LOGGER" message="#[payload as Array]" /> | ||
<!-- Transform Message 1 --> | ||
<ee:transform doc:name="Transform Message"> | ||
<ee:message> | ||
<ee:set-payload><![CDATA[%dw 2.0 | ||
output application/json | ||
--- | ||
(payload)]]></ee:set-payload> | ||
</ee:message> | ||
</ee:transform> | ||
<!-- Second Logger --> | ||
<logger level="INFO" doc:name="Logger 2" | ||
message="#[payload]" | ||
category="AGGREGATOR: SECOND LOGGER" /> | ||
<!-- Transform Message --> | ||
<ee:transform doc:name="Transform Message" > | ||
<ee:message> | ||
<ee:set-payload><![CDATA[%dw 2.0 | ||
output application/json | ||
--- | ||
(payload + 100)]]></ee:set-payload> | ||
</ee:message> | ||
</ee:transform> | ||
<!-- Third Logger --> | ||
<logger level="INFO" doc:name="Logger 3" | ||
message="#[payload]" | ||
category="AGGREGATOR: THIRD LOGGER" /> | ||
</batch:aggregator> | ||
</batch:step> | ||
</batch:process-records> | ||
</batch:job> | ||
</flow> | ||
---- | ||
|
||
* Logger 1, the first Logger component within the Aggregator, receives the array as a non-repeatable stream (`stream`), so it prints `[1, 2]` but passes an empty array `[]` to the next component in the Aggregator. | ||
* The first Transform Message component receives the empty array from Logger 1 and sends it to Logger 2. So Logger 2 prints an _empty_ array (`[ ]`). | ||
* The second Transform Message component appends `100` to the empty array, so Logger 3 prints the new payload, `[100]`. | ||
|
||
The Loggers print the following (edited for readability): | ||
|
||
[source,logs] | ||
---- | ||
INFO ...AGGREGATOR: FIRST LOGGER: [1, 2] | ||
INFO ...AGGREGATOR: SECOND LOGGER: [ | ||
] | ||
INFO ... AGGREGATOR: THIRD LOGGER: [ | ||
100 | ||
] | ||
---- | ||
|
||
Unlike the Logger, a Transform Message, converts its input into a non-streamed form. So a Logger located downstream of such a component does not receive a streamed payload. | ||
|
||
Assume a scenario in which the first Transform Message component from the << example_non_repeatable_stream, preceding example>> is located _before_ the Logger 1. In this case, the Logger prints the following (edited): | ||
|
||
[source,logs] | ||
---- | ||
INFO ...AGGREGATOR: FIRST LOGGER: [ | ||
1, | ||
2 | ||
] | ||
INFO ...AGGREGATOR: SECOND LOGGER: [ | ||
1, | ||
2 | ||
] | ||
INFO ... AGGREGATOR: THIRD LOGGER: [ | ||
1, | ||
2 | ||
100 | ||
] | ||
---- | ||
|
||
* Transform Message receives the streamed payload from the Aggregator but converts it to a non-streamed form. So the flow passes the unmodified array to Logger 1. | ||
* Logger 1 prints the unmodified array in the payload, so it prints that array, `[1,2]`. | ||
* The second Transform Message component appends `100` to the array, so Logger 3 prints the modified array, `[1,2,100]`. | ||
|
||
|
||
== See Also | ||
|
||
xref:dataweave::dataweave-types.adoc#dw_type_string[DataWeave String Type] | ||
* xref:streaming-about.adoc[] | ||
* xref:dataweave::dataweave-types.adoc#dw_type_string[DataWeave String Type] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved to reference