|
| 1 | +--- |
| 2 | +sidebar_position: 14 |
| 3 | +--- |
| 4 | + |
| 5 | +# Logging |
| 6 | + |
| 7 | +All SeaTunnel Engine processes create a log text file that contains messages for various events happening in that process. These logs provide deep insights into the inner workings of SeaTunnel Engine, and can be used to detect problems (in the form of WARN/ERROR messages) and can help in debugging them. |
| 8 | + |
| 9 | +The logging in SeaTunnel Engine uses the SLF4J logging interface. This allows you to use any logging framework that supports SLF4J, without having to modify the SeaTunnel Engine source code. |
| 10 | + |
| 11 | +By default, Log4j 2 is used as the underlying logging framework. |
| 12 | + |
| 13 | +## Structured logging |
| 14 | + |
| 15 | +SeaTunnel Engine adds the following fields to MDC of most of the relevant log messages (experimental feature): |
| 16 | + |
| 17 | +- Job ID |
| 18 | + - key: ST-JID |
| 19 | + - format: string |
| 20 | + |
| 21 | +This is most useful in environments with structured logging and allows you to quickly filter the relevant logs. |
| 22 | + |
| 23 | +The MDC is propagated by slf4j to the logging backend which usually adds it to the log records automatically (e.g. in log4j json layout). Alternatively, it can be configured explicitly - log4j pattern layout might look like this: |
| 24 | + |
| 25 | +```properties |
| 26 | +[%X{ST-JID}] %c{0} %m%n. |
| 27 | +``` |
| 28 | + |
| 29 | +## Configuring Log4j2 |
| 30 | + |
| 31 | +Log4j 2 is controlled using property files. |
| 32 | + |
| 33 | +The SeaTunnel Engine distribution ships with the following log4j properties files in the `confing` directory, which are used automatically if Log4j 2 is enabled: |
| 34 | + |
| 35 | +- `log4j2_client.properties`: used by the command line client (e.g., `seatunnel.sh`) |
| 36 | +- `log4j2.properties`: used for SeaTunnel Engine server processes (e.g., `seatunnel-cluster.sh`) |
| 37 | + |
| 38 | +By default, log files are output to the `logs` directory. |
| 39 | + |
| 40 | +Log4j periodically scans this file for changes and adjusts the logging behavior if necessary. By default this check happens every 60 seconds and is controlled by the monitorInterval setting in the Log4j properties files. |
| 41 | + |
| 42 | +### Configure to output separate log files for jobs |
| 43 | + |
| 44 | +To output separate log files for each job, you can update the following configuration in the `log4j2.properties` file: |
| 45 | + |
| 46 | +```properties |
| 47 | +... |
| 48 | +rootLogger.appenderRef.file.ref = routingAppender |
| 49 | +... |
| 50 | + |
| 51 | +appender.file.layout.pattern = %d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%-30.30c{1.}] [%t] - %m%n |
| 52 | +... |
| 53 | +``` |
| 54 | + |
| 55 | +This configuration generates separate log files for each job, for example: |
| 56 | + |
| 57 | +``` |
| 58 | +job-xxx1.log |
| 59 | +job-xxx2.log |
| 60 | +job-xxx3.log |
| 61 | +... |
| 62 | +``` |
| 63 | + |
| 64 | +### Configuring output mixed logs |
| 65 | + |
| 66 | +*This configuration mode by default.* |
| 67 | + |
| 68 | +To all job logs output into SeaTunnel Engine system log file, you can update the following configuration in the `log4j2.properties` file: |
| 69 | + |
| 70 | +```properties |
| 71 | +... |
| 72 | +rootLogger.appenderRef.file.ref = fileAppender |
| 73 | +... |
| 74 | + |
| 75 | +appender.file.layout.pattern = [%X{ST-JID}] %d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%-30.30c{1.}] [%t] - %m%n |
| 76 | +... |
| 77 | +``` |
| 78 | + |
| 79 | +### Compatibility with Log4j1/Logback |
| 80 | + |
| 81 | +SeaTunnel Engine automatically integrates Log framework bridge, allowing existing applications that work against Log4j1/Logback classes to continue working. |
| 82 | + |
| 83 | +## Best practices for developers |
| 84 | + |
| 85 | +You can create an SLF4J logger by calling `org.slf4j.LoggerFactory#LoggerFactory.getLogger` with the Class of your class as an argument. |
| 86 | + |
| 87 | +Of course, you can also use `lombok` annotation `@Slf4j` to achieve the same effect. |
| 88 | + |
| 89 | +```java |
| 90 | +import org.slf4j.Logger; |
| 91 | +import org.slf4j.LoggerFactory; |
| 92 | + |
| 93 | +public class TestConnector { |
| 94 | + private static final Logger LOG = LoggerFactory.getLogger(TestConnector.class); |
| 95 | + |
| 96 | + public static void main(String[] args) { |
| 97 | + LOG.info("Hello world!"); |
| 98 | + } |
| 99 | +} |
| 100 | +``` |
| 101 | + |
| 102 | +In order to benefit most from SLF4J, it is recommended to use its placeholder mechanism. Using placeholders allows avoiding unnecessary string constructions in case that the logging level is set so high that the message would not be logged. |
| 103 | + |
| 104 | +The syntax of placeholders is the following: |
| 105 | + |
| 106 | +```java |
| 107 | +LOG.info("This message contains {} placeholders. {}", 1, "key1"); |
| 108 | +``` |
| 109 | + |
| 110 | +Placeholders can also be used in conjunction with exceptions which shall be logged. |
| 111 | + |
| 112 | +```java |
| 113 | +try { |
| 114 | + // some code |
| 115 | +} catch (Exception e) { |
| 116 | + LOG.error("An {} occurred", "error", e); |
| 117 | +} |
| 118 | +``` |
0 commit comments