## 4 Results of the Software-Prototyping
### From Logging to Structured Logging  
The logging instrumentation is quite simple for developers and works mainly programming language specific but basically according to the following principle illustrated in Python. A logging library must often be imported, defining so-called log levels such as DEBUG, INFO, WARNING, ERROR, FATAL, and others. While the application is running, a log level is usually set via an environment variable, e.g., INFO. All log calls above this level are then written to a log file. ```
importlogginglogging.basicConfig(filename=\"example.log\",level=logging.DEBUG)logging.debug(\"Performing_user_check\")user=\"NameKratzke\">logging.info(\"User{user}triestologin.\")logging.warning(f^User{user}notfound')?logging.error(f^User_user_\



The resulting log files are still readable for administrators and developers (even if a bit more unwieldy) but much better processable and analyzable by databases such as ElasticSearch. Quantitative metrics can also be recorded in this way. Structured logging can thus also be used for the recording of quantitative metrics:
```
1 importlog12
[...]
3 log12.info(''Openrequests'',requests=len(requests))
```
```
1{'event'':''Openrequests'',''requests'':42}
```

Furthermore, this structured logging approach can also be used to create tracings. In distributed tracing systems, a trace identifier (ID) is created for each transaction that passes through a distributed system. The individual steps are so-called spans. These are also assigned an identifier (span ID). The span ID is then linked to the trace ID, and the runtime is measured and logged. In this way, the time course of distributed transactions can be tracked along the components involved, and, for example, the duration of individual processing steps can be determined. ### Resulting and Simplified Logging Architecture

Thus, the two principles to print logs simply to standard outout (stdout) and to log in a structured and text-based data format are applied consequently. The resulting observability system complexity thus reduces from Figure 2 to Figure 4 because all system components can collect log, metric, and trace information in the same style that can be routed seamlessly from an operation platform provided log forwarder (already existing technology) to a central analytical database. ### Study Outcome: Unified Instrumentation via a Structured Logging Library (Prototype)

This paper will briefly explain below the way to capture events, metrics, and traces using the logging prototype that emerged. The prototype library log12 was developed in Python 3 but can be implemented in other programming languages analogously. Figure 4: An observability system consistently based on structured logging with significantly reduced complexity. **log12** will create automatically for each event additional key-value attributes like a unique identifier (that is used to relate child events to parent events and even remote events in distributed tracing scenarios) and start and completion timestamps that can be used to measure the runtime of events (although known from distributed tracing libraries but not common for logging libraries). It is explained:

* how to create a log stream;
* how an event in a log stream is created and logged;
* how a child event can be created and assigned to a parent event (to trace and record runtimes of more complex and dependent chains of events within the same process);
* and how to make use of the distributed tracing features to trace events that pass through a chain of services in a distributed service of services system). The following lines of code create a log stream with the name \"logstream\" that is logged to stdout, see Listing 1:

```
1 importlog12 log=log12.logging(''logstream'',
3 general=''value'',tag=''foo'',service_mark=''test'')
```

**Listing 1** Creating an event log stream in log12.