# Logging

### KLog Class Overview

* **Built on Standard Java Logging**\
  Utilizes the built-in java.util.logging framework, part of Java SE. No additional external libraries, such as Apache Log4j, are required.
* **High Performance**\
  Capable of logging over 10,000 lines per second on a MacBook Pro when using the FileHandler and KLogLineFormatter.
* **Simplified Logging**\
  Streamlines logging with straightforward methods for debug, error, and info messages.
* **Static Methods**\
  All methods are static, eliminating the need for instantiation.
* **Flexible Handlers and Formatters**\
  Includes handlers and formatters for generating log output in various formats: tabular text, CSV, XML, JSON, and YAML. Supports sending logs to JDBC-compliant databases or routing error logs to any SMTP server.
* **Enhanced Log Details**\
  Provides precise timestamps and exact code locations in formatted log outputs.
* **Configuration and Runtime Adjustments**\
  Logging is enabled via the *KLog.properties* configuration file, which must be located in the current directory or set thru the startup parameter *KLogPropertyFile*. Logging levels can dynamically be adjusted and log entries may be filtered at runtime.

{% hint style="info" %}
The Java utility package uses KLog internally to assist with problem determination. Setting the log level to *FINEST* in the *KLog.properties* file enables detailed debugging mode, providing comprehensive insights during code execution.
{% endhint %}

### Logging Handlers

In addition to the standard logging handlers for console and file output, KLog provides the additional classes:

* **KLogJDBCHandler**: Write each log entry to any JDBC compliant database
* **KLogSMTPHandler**: Send error log entries (FATAL logging level) to any SMTP server

### Logging Formatters

The log information (timestamp, logging level, code location and message) can be formatted with the additional formatter classes:

* **KLogCSVFormatter**: Format each log entry as a one-line CSV string
* **KLogJSONFormatter**: Format each log entry as a multi-line JSON string
* **KLogLineFormatter**: Format each log entry as a one-line tabular string
* **KLogXMLFormatter**: Format each log entry as a multi-line XML string
* **KLogYAMLFormatter**: Format each log entry as a multi-line YAML string

### Sample Properties Files

The logging properties file enables and configures the logging framework used by all `KLog` methods. Simply download, edit and and place it in the current directory of your application.

{% file src="/files/OY3Oy56cHOWd632JXnp2" %}
Recommended minimal logging (errors only)
{% endfile %}

{% file src="/files/HjQM7XYniq8tl4Pbooe6" %}
Full logging functionality
{% endfile %}

### Special Properties

<details>

<summary>Startup System Properties</summary>

| Command Line Option | Default                         | Purpose                                                     |
| ------------------- | ------------------------------- | ----------------------------------------------------------- |
| -DKLogPropertyFile  | "KLog.properties"               | Path and file name of KLog properties file                  |
| -DKLogLevel         | Set by the KLog properties file | Override KLog level to Info, Error,  Debug or Off           |
| -DKLogInclude       | Set by the KLog properties file | Limit log entries to specified RegEx match, e.g. “password“ |
| -DKLogExclude       | Set by the KLog properties file | Exclude log entries matching RegEx, e.g. “started\|ended“   |

Examples

```bash
% java -DKLogInclude=“Started|Ended“ YourApp
```

<pre class="language-bash"><code class="lang-bash"><strong>% java -DKLogPropertyFile=/etc/KLog.properties -DKLogLevel=Debug YourApp
</strong></code></pre>

{% hint style="warning" %}
Please note that all command line options are case sensitive.
{% endhint %}

</details>

<details>

<summary>Common KLog Properties</summary>

| Property Key             | Value                     | Notes                                                      |
| ------------------------ | ------------------------- | ---------------------------------------------------------- |
| ch.k43.util.KLog.level   | FINEST, INFO, SEVERE, OFF | Corresponds to KLog logging levels Debug, Info, Error, Off |
| ch.k43.util.KLog.exclude | RegEx Pattern             | Exclude matching log entries, e.g. “password“              |
| ch.k43.util.KLog.include | RexEx Pattern             | Include only matching log entries, e.g. “started\|ended“   |

</details>

<details>

<summary>KLog.properties for KLogJDBCHandler</summary>

| Property Key                              | Value                | Notes                                       |
| ----------------------------------------- | -------------------- | ------------------------------------------- |
| ch.k43.util.KLogJDBCHandler.jdbc.driver   | JDBC Driver Class    | Java class name, e.g. org.h2.Driver         |
| ch.k43.util.KLogJDBCHandler.jdbc.url      | Connection URL       | e.g. jdbc:h2:mem:mydb                       |
| ch.k43.util.KLogJDBCHandler.jdbc.username | Connection user name | e.g. johnsmith                              |
| ch.k43.util.KLogJDBCHandler.jdbc.password | Connection password  | e.g. Pa$$w0rd                               |
| ch.k43.util.KLogJDBCHandler.tablename     | Database table name  | Table name to be used, e.g. KLOGDATA        |
| ch.k43.util.KLogJDBCHandler.retensiondays | Number               | Number of days to keep log entries, e.g. 14 |
| ch.k43.util.KLogJDBCHandler.debug         | true, false          | Send debug data to standard output (stdout) |

</details>

<details>

<summary>KLog.properties for KLogSMTPHandler</summary>

| Property Key                              | Value                                   | Notes                                       |
| ----------------------------------------- | --------------------------------------- | ------------------------------------------- |
| ch.k43.util.KLogSMTPHandler.mail.from     | Sender Address                          | e.g. <johnsmith@acme.com>                   |
| ch.k43.util.KLogSMTPHandler.mail.to       | Recipient Address                       | e.g. <fred@hotmail.com>                     |
| h.k43.util.KLogSMTPHandler.mail.subject   | Email subject                           | e.g. "Application Error"                    |
| ch.k43.util.KLogSMTPHandler.smtp.hostname | SMTP hostname                           | e.g. mail.acme.com                          |
| ch.k43.util.KLogSMTPHandler.smtp.hostport | SMTP port number                        | e.g. 25                                     |
| ch.k43.util.KLogSMTPHandler.smtp.username | SMTP authentication user name (or none) | e.g. <johnsmith@acme.com>                   |
| ch.k43.util.KLogSMTPHandler.smtp.password | SMTP authentication password (or none)  | e.g. Pa$$w0rd                               |
| ch.k43.util.KLogSMTPHandler.smtp.tls      | true, false                             | Use TLS or Non-TLS connection               |
| ch.k43.util.KLogSMTPHandler.threshold     | Number                                  | Maximum number of email sent per minute     |
| ch.k43.util.KLogSMTPHandler.debug         | true, false                             | Send debug data to standard output (stdout) |

</details>

<details>

<summary>KLog.properties for KLogCSVFormatter</summary>

| Property Key                             | Value       | Notes                              |
| ---------------------------------------- | ----------- | ---------------------------------- |
| ch.k43.util.KLogCSVFormatter.writeheader | true, false | Add header lines with column names |

</details>

### Examples

<details>

<summary>Code and Output</summary>

<pre class="language-java"><code class="lang-java"><strong>KLog.info("Program started");
</strong>		
int rc = -1;
KLog.error(rc != 0, "Return code is {}", rc);
	
KLog.debug("Just a debug message");
		
Exception e = new Exception("Program error");
KLog.error(e);
		
KLog.info("Program ended");
</code></pre>

```
2024-08-29T15:49:27.867 D main[1]:ch.k43.util.KLog:open:462                            ===== Application started 2024-08-29T15:49:27.850 =====
2024-08-29T15:49:27.867 D main[1]:ch.k43.util.KLog:open:464                            Java Utility Package (Freeware) ch.k43.util Version 2024.08.29
2024-08-29T15:49:27.868 D main[1]:ch.k43.util.KLog:open:467                            Homepage java-util.k43.ch - Please send any feedback to andy.brunner@k43.ch
2024-08-29T15:49:27.889 D main[1]:ch.k43.util.KLog:open:469                            Host ab-macbook-pro (10.0.0.105)
2024-08-29T15:49:27.889 D main[1]:ch.k43.util.KLog:open:470                            OS platform Mac OS X (Version 14.6.1/aarch64)
2024-08-29T15:49:27.889 D main[1]:ch.k43.util.KLog:open:471                            Java version 17 (OpenJDK 64-Bit Server VM - Eclipse Adoptium)
2024-08-29T15:49:27.891 D main[1]:ch.k43.util.KLog:open:475                            Java heap maximum 16.00 GB, current 1.00 GB, used 4.80 MB, free 1019.20 MB
2024-08-29T15:49:27.891 D main[1]:ch.k43.util.KLog:open:479                            Java locale de/CH, local time UTC +02:00
2024-08-29T15:49:27.891 D main[1]:ch.k43.util.KLog:open:482                            Java classpath ../bin/:../lib/org.json.20230618.jar:../lib/jakarta-mail-1.6.7.jar
2024-08-29T15:49:27.891 I main[1]:Test:main:10                                         Program started
2024-08-29T15:49:27.892 E main[1]:Test:main:13                                         ===> Return code is -1
2024-08-29T15:49:27.892 D main[1]:Test:main:15                                         Just a debug message
2024-08-29T15:49:27.892 E main[1]:Test:main:18                                         ===> java.lang.Exception: Program error
2024-08-29T15:49:27.892 E main[1]:Test:main:18                                         ===> Stack[1]: Test.main(Test.java:17)
2024-08-29T15:49:27.892 I main[1]:Test:main:20                                         Program ended
```

</details>

<details>

<summary>Log Exception</summary>

```java
try {
   ...
} catch (Exception e) {
   KLog.error(e);
}
```

</details>

<details>

<summary>Log and Throw RuntimeException</summary>

```java
try {
  ...
} catch (Exception e) {
  KLog.abort(e.toString());
}
```

</details>

<details>

<summary>Log and Throw IllegalArgumentException</summary>

```java
public divide(double arg1, double arg2) {
  // Check arguments
  KLog.argException(arg2 == 0.0, "Divisor 0 not allowed");
  ...
}
```

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://java-util.k43.ch/examples/logging.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
