Skip to content
This repository was archived by the owner on Jan 6, 2023. It is now read-only.

Commit 28454d8

Browse files
committed
Merge branch 'weblogic-json-logging'
2 parents 3d5a56a + b61943f commit 28454d8

File tree

7 files changed

+246
-66
lines changed

7 files changed

+246
-66
lines changed

README.md

+35-25
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ The `weblogic-logging-exporter.jar` will be available under the `target` directo
9696

9797
## Installation
9898

99-
This section outlines the steps that are required to add the Weblogic Logging Exporter to Weblogic Server.
99+
This section outlines the steps that are required to add the WebLogic Logging Exporter to WebLogic Server.
100100

101101
1. Download or build the WebLogic Logging Exporter as described above.
102102

@@ -125,9 +125,9 @@ This section outlines the steps that are required to add the Weblogic Logging Ex
125125
you can find this JAR file in your local maven repository at `~/.m2/repository/org/yaml/snakeyaml/1.27/snakeyaml-1.27.jar`.
126126
Otherwise, you can download it from [Maven Central](https://search.maven.org/artifact/org.yaml/snakeyaml/1.27/bundle).
127127
128-
Place this file in a suitable location, e.g. your domain directory.
128+
Place the file(s) in a suitable location, e.g. your domain directory.
129129
130-
Update the server classpath to include these two files. This can be done by adding a statement to the end of your
130+
Update the server classpath to include these file(s). This can be done by adding a statement to the end of your
131131
`setDomainEnv.sh` script in your domain's `bin` directory as follows (this example assumes your domain
132132
directory is `/u01/base_domain`):
133133
@@ -137,33 +137,43 @@ This section outlines the steps that are required to add the Weblogic Logging Ex
137137
138138
1. Create a configuration file for the WebLogic Logging Exporter.
139139
140-
Create a file named `WebLogicLoggingExporter.yaml` in your domain's `config` directory. You can copy the
141-
[sample provided in this project](samples/WebLogicLoggingExporter.yaml) as a starting point. That sample
142-
contains details of all of the available configuration options. A completed configuration file might look
143-
like this:
140+
There are two options currently - the version 1.x configuration, or the new version 2.x configuration - please
141+
note that the 2.x configuration is `alpha` and therefore subject to change as we get close to the 2.0 release.
144142
145-
```
146-
publishHost: localhost
147-
publishPort: 9200
148-
domainUID: domain1
149-
weblogicLoggingExporterEnabled: true
150-
weblogicLoggingIndexName: domain1-wls
151-
weblogicLoggingExporterSeverity: Notice
152-
weblogicLoggingExporterBulkSize: 1
153-
weblogicLoggingExporterFilters:
154-
- filterExpression: 'severity > Warning'
155-
```
143+
a. Version 1.x configuration
144+
145+
Create a file named `WebLogicLoggingExporter.yaml` in your domain's `config` directory. You can copy the
146+
[sample provided in this project](samples/WebLogicLoggingExporter.yaml) as a starting point. That sample
147+
contains details of all of the available configuration options. A completed configuration file might look
148+
like this:
149+
150+
```
151+
publishHost: localhost
152+
publishPort: 9200
153+
domainUID: domain1
154+
weblogicLoggingExporterEnabled: true
155+
weblogicLoggingIndexName: domain1-wls
156+
weblogicLoggingExporterSeverity: Notice
157+
weblogicLoggingExporterBulkSize: 1
158+
weblogicLoggingExporterFilters:
159+
- filterExpression: 'severity > Warning'
160+
```
161+
162+
Note that you must give a unique `domainUID` to each domain. This value is used to filter logs by domain when you
163+
send the logs from multiple domains to the same Elasticsearch server. If you are using the WebLogic Kubernetes
164+
Operator, it is strongly recommended that you use the same `domainUID` value that you use for the domain.
165+
166+
It is also strongly recommended that you consider using a different Elastcsearch index name for each domain.
156167
157-
Note that you must give a unique `domainUID` to each domain. This value is used to filter logs by domain when you
158-
send the logs from multiple domains to the same Elasticsearch server. If you are using the WebLogic Kubernetes
159-
Operator, it is strongly recommended that you use the same `domainUID` value that you use for the domain.
168+
b. Version 2.x configuration
160169
161-
It is also strongly recommended that you consider using a different Elastcsearch index name for each domain.
170+
If you prefer to place the configuration file in a different location, you can set the environment variable
171+
`WEBLOGIC_LOGGING_EXPORTER_CONFIG_FILE` to point to the location of the file.
162172
163-
If you prefer to place the configuration file in a different location, you can set the environment variable
164-
`WEBLOGIC_LOGGING_EXPORTER_CONFIG_FILE` to point to the location of the file.
173+
If you want to write the JSON logs to a file instead of sending it elasticsearch directly use the following configuration
174+
[file](samples/WebLogicFileLoggingExporter.yaml) and adjust it to your needs. Make sure to rename it to WebLogicLoggingExporter.yaml.
165175
166-
1. Restart the servers to activate the changes. After restarting the servers, they will load the WebLogic
176+
6. Restart the servers to activate the changes. After restarting the servers, they will load the WebLogic
167177
Logging Exporter and start sending their logs to the specified Elasticsearch instance. You can then
168178
access them in Kibana as shown in the example below. You will need to create an index first and then go to
169179
the visualization page.

pom.xml

+34-2
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,9 @@
8585
</configuration>
8686
</plugin>
8787
<plugin>
88+
<groupId>org.apache.maven.plugins</groupId>
8889
<artifactId>maven-failsafe-plugin</artifactId>
89-
<version>2.22.1</version>
90+
<version>2.22.2</version>
9091
</plugin>
9192
<!-- end -->
9293
<plugin>
@@ -109,6 +110,26 @@
109110
</execution>
110111
</executions>
111112
</plugin>
113+
<!--
114+
<plugin>
115+
<groupId>org.apache.maven.plugins</groupId>
116+
<artifactId>maven-assembly-plugin</artifactId>
117+
<version>3.3.0</version>
118+
<executions>
119+
<execution>
120+
<phase>package</phase>
121+
<goals>
122+
<goal>single</goal>
123+
</goals>
124+
</execution>
125+
</executions>
126+
<configuration>
127+
<descriptorRefs>
128+
<descriptorRef>jar-with-dependencies</descriptorRef>
129+
</descriptorRefs>
130+
</configuration>
131+
</plugin>
132+
-->
112133
</plugins>
113134
</build>
114135

@@ -190,13 +211,24 @@
190211
<artifactId>snakeyaml</artifactId>
191212
<version>1.27</version>
192213
</dependency>
214+
<dependency>
215+
<groupId>co.elastic.logging</groupId>
216+
<artifactId>jul-ecs-formatter</artifactId>
217+
<version>1.2.0</version>
218+
</dependency>
219+
<dependency>
220+
<groupId>org.slf4j</groupId>
221+
<artifactId>slf4j-jdk14</artifactId>
222+
<version>1.7.32</version>
223+
</dependency>
193224
<dependency>
194225
<groupId>org.antlr</groupId>
195226
<artifactId>antlr-complete</artifactId>
196227
<version>3.5.2</version>
228+
<!-- we need it in unit tests but the weblogic runtime provides it at run time -->
229+
<scope>test</scope>
197230
</dependency>
198231
</dependencies>
199-
200232
<reporting>
201233
<plugins>
202234
<plugin>
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# turn off the elasticsearch output
2+
weblogicLoggingExporterEnabled: false
3+
4+
# configure json logging output
5+
writeToFileEnabled: true
6+
# %g is necessary for rollback of log files.
7+
outputFile: '/var/log/oracle/json-logging%g.log'
8+
# Max open files
9+
maxRollbackFiles: 3
10+
# Max file size in bytes, this is 50 MB
11+
maxFileSize: 52428800
12+
# Should the log file be appended to when the new logger is created
13+
appendToFile: true
14+
# Optional configuration for specifying which levels get logged to the json log file.
15+
# fileLoggingLogLevel: INFO

src/main/java/weblogic/logging/exporter/Startup.java

+27-10
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@
44
package weblogic.logging.exporter;
55

66
import java.io.File;
7+
import java.util.logging.FileHandler;
8+
import java.util.logging.Level;
79
import java.util.logging.Logger;
10+
811
import weblogic.logging.LoggingHelper;
12+
import weblogic.logging.ServerLoggingHandler;
913
import weblogic.logging.exporter.config.Config;
1014

1115
public class Startup {
1216

1317
private static final String DEFAULT_CONFIG_FILE = "config/WebLogicLoggingExporter.yaml";
1418

1519
public static void main(String[] argv) {
16-
System.out.println("======================= Weblogic Logging Exporter Startup class called");
20+
System.out.println("======================= WebLogic Logging Exporter Startup class called");
1721
try {
18-
// Logger logger = LoggingHelper.getDomainLogger();
1922
Logger logger = LoggingHelper.getServerLogger();
2023

2124
/*
@@ -26,27 +29,41 @@ public static void main(String[] argv) {
2629
*/
2730

2831
String fileName =
29-
System.getProperty(
30-
"WEBLOGIC_LOGGING_EXPORTER_CONFIG_FILE",
31-
System.getenv("WEBLOGIC_LOGGING_EXPORTER_CONFIG_FILE"));
32+
System.getProperty(
33+
"WEBLOGIC_LOGGING_EXPORTER_CONFIG_FILE",
34+
System.getenv("WEBLOGIC_LOGGING_EXPORTER_CONFIG_FILE"));
3235
System.out.println(
33-
"JavaProperty/EnvVariable WEBLOGIC_LOGGING_EXPORTER_CONFIG_FILE:" + fileName);
36+
"JavaProperty/EnvVariable WEBLOGIC_LOGGING_EXPORTER_CONFIG_FILE:" + fileName);
3437
if (fileName == null || fileName.isEmpty()) {
3538
System.out.println(
36-
"Env variable WEBLOGIC_LOGGING_EXPORTER_CONFIG_FILE is not set. Defaulting to:"
37-
+ DEFAULT_CONFIG_FILE);
39+
"Env variable WEBLOGIC_LOGGING_EXPORTER_CONFIG_FILE is not set. Defaulting to:"
40+
+ DEFAULT_CONFIG_FILE);
3841
fileName = DEFAULT_CONFIG_FILE;
3942
}
4043
File file = new File(fileName);
4144
System.out.println("Reading configuration from file name: " + file.getAbsolutePath());
4245
Config config = Config.loadConfig(file);
4346
System.out.println(config);
47+
48+
// Elastic log handler is enabled or the file log handler
4449
if (config.getEnabled()) {
4550
logger.addHandler(new LogExportHandler(config));
51+
} else if (config.isFileLoggingEnabled()) {
52+
// Because of this bridge log messages in the applications themselves are being forwarded to the server logger.
53+
// so that logging in ear/war artifacts are also visible to the server logger and appear in the JSON log file.
54+
Logger.getLogger("").addHandler(new ServerLoggingHandler());
55+
56+
// Register a file handler using the provided config
57+
FileHandler fh = new FileHandler(config.getOutputFile(), config.getMaxFileSize(), config.getGetMaxRollbackFiles(), config.getAppendToFile());
58+
fh.setLevel(Level.parse(config.getFileLoggingLogLevel()));
59+
fh.setFormatter(new WebLogicLogFormatter(config.getDomainUID()));
60+
logger.addHandler(fh);
4661
} else {
47-
System.out.println("WebLogic Logging Exporter is disabled");
62+
System.out.println("WebLogic Elasticsearch Logging Exporter is disabled");
4863
}
49-
} catch (Exception e) {
64+
// also catch errors so that WebLogic does not crash when a required library was not placed in the classpath correctly.
65+
} catch (Error | Exception e) {
66+
System.out.println("======================= Something went wrong, the WebLogic Logging Exporter is not activated");
5067
e.printStackTrace();
5168
}
5269
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (c) 2018, 2021, Oracle and/or its affiliates.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
3+
4+
package weblogic.logging.exporter;
5+
6+
import co.elastic.logging.jul.EcsFormatter;
7+
import org.slf4j.MDC;
8+
import weblogic.logging.WLLogRecord;
9+
10+
import java.util.logging.LogRecord;
11+
12+
public class WebLogicLogFormatter extends EcsFormatter {
13+
public static final String FIELDS_MESSAGE_ID = "fields.messageID";
14+
public static final String FIELDS_SERVER_NAME = "fields.serverName";
15+
public static final String FIELDS_USER_ID = "fields.userId";
16+
public static final String FIELDS_SUB_SYSTEM = "fields.subSystem";
17+
public static final String FIELDS_MACHINE_NAME = "fields.machineName";
18+
public static final String FIELDS_TRANSACTION_ID = "fields.transactionId";
19+
public static final String FIELDS_DIAGNOSTIC_CONTEXT_ID = "fields.diagnosticContextId";
20+
public static final String FIELDS_SEQUENCE_NUMBER = "fields.sequenceNumber";
21+
public static final String FIELDS_DOMAIN_UID = "fields.domainUID";
22+
23+
private final String domainUID;
24+
25+
public WebLogicLogFormatter(String domainUID) {
26+
this.domainUID = domainUID;
27+
}
28+
29+
@Override
30+
public String format(final LogRecord record) {
31+
WLLogRecord wlLogRecord = (WLLogRecord) record;
32+
33+
MDC.put(FIELDS_MESSAGE_ID, wlLogRecord.getId());
34+
MDC.put(FIELDS_SERVER_NAME, wlLogRecord.getServerName());
35+
MDC.put(FIELDS_USER_ID, wlLogRecord.getUserId());
36+
MDC.put(FIELDS_SUB_SYSTEM, wlLogRecord.getSubsystem());
37+
MDC.put(FIELDS_MACHINE_NAME, wlLogRecord.getMachineName());
38+
MDC.put(FIELDS_TRANSACTION_ID, wlLogRecord.getTransactionId());
39+
MDC.put(FIELDS_DIAGNOSTIC_CONTEXT_ID, wlLogRecord.getDiagnosticContextId());
40+
MDC.put(FIELDS_SEQUENCE_NUMBER, String.valueOf(wlLogRecord.getSequenceNumber()));
41+
MDC.put(FIELDS_DOMAIN_UID, domainUID);
42+
43+
String result = super.format(wlLogRecord);
44+
45+
// Can't clear the whole MDC HashMap as there might be other records in there.
46+
MDC.remove(FIELDS_MESSAGE_ID);
47+
MDC.remove(FIELDS_SERVER_NAME);
48+
MDC.remove(FIELDS_USER_ID);
49+
MDC.remove(FIELDS_SUB_SYSTEM);
50+
MDC.remove(FIELDS_MACHINE_NAME);
51+
MDC.remove(FIELDS_TRANSACTION_ID);
52+
MDC.remove(FIELDS_DIAGNOSTIC_CONTEXT_ID);
53+
MDC.remove(FIELDS_SEQUENCE_NUMBER);
54+
MDC.remove(FIELDS_DOMAIN_UID);
55+
56+
return result;
57+
}
58+
}

0 commit comments

Comments
 (0)