Hi all,

As we progress with the Go implementation of Apache Synapse, a robust and
efficient logging strategy is crucial. Currently, the Java-based Apache
Synapse leverages Apache Commons Logging and Log4j, offering features such
as:

   - Structured logging (key-value pairs)
   - Multiple log severity levels (e.g., DEBUG, INFO, WARN, ERROR)
   - Various output destinations (console, file, etc.)
   - Log file rotation (time and size based)
   - Package-specific log level configuration
   - Dynamic runtime log level adjustments

For the Go implementation, I've explored several popular logging libraries,
including:

   - Zap: https://go.uber.org/zap
   <https://www.google.com/url?sa=E&source=gmail&q=https://go.uber.org/zap>
   - Logrus: https://github.com/sirupsen/logrus
   
<https://www.google.com/url?sa=E&source=gmail&q=https://github.com/sirupsen/logrus>
   - slog (Go standard library): https://pkg.go.dev/log/slog
   <https://www.google.com/url?sa=E&source=gmail&q=https://pkg.go.dev/log/slog>

After thorough evaluation, I propose adopting slog for our logging needs.
Here's a comparison of the key aspects:
Feature Zap Logrus slog
Performance High (optimized for speed) Moderate High (standard library,
optimized)
Structure Strongly typed, structured logs Structured logs (flexible
formats) Strongly
typed, structured logs
Standard Library No No Yes
Extensibility High (custom encoders) High (hooks, formatters) High
(handlers, attributes)

While Zap excels in raw performance, its CPU usage can be significant under
heavy load. Conversely, while slog is very performant, some benchmarks show
higher memory consumption than zap. However, considering Synapse's core
function as a mediation engine, where predictable and reliable performance
is paramount, and the fact that memory consumption is more manageable than
cpu consumption in our use cases, slog's advantages outweigh its drawbacks.

Here's why I suggest slog is the optimal choice for Apache Synapse Go:

   - Standard Library Integration: Leveraging slog minimizes external
   dependencies. This is crucial for long-term maintainability and reduces the
   risk of dependency conflicts, aligning with our architectural principles of
   stability and simplicity. Staying within the standard library provides a
   stable foundation for future Go versions.
   - Performance and Structure: slog offers excellent performance and
   structured logging capabilities, which are essential for debugging and
   monitoring a complex mediation engine.
   - Extensibility: slog's handler-based architecture allows for flexible
   customization and integration with various output destinations.
   - Future Proofing: slog is part of the standard library, ensuring it
   will be maintained and improved by the Go team.

One of the significant challenges is replicating the package-level log
level control and hot-deploying log level changes found in the current
Java-based Synapse. Mainstream Go logging libraries do not inherently
provide this functionality. To address this, I've implemented a prototype
that allows for dynamic log level configuration on a per-package struct
basis. This enables granular control over log verbosity, similar to the
existing Synapse implementation.

Regarding log rotation, slog does not provide built-in log rotation.
Therefore, I recommend using lumberjack (
https://github.com/natefinch/lumberjack
<https://www.google.com/url?sa=E&source=gmail&q=https://github.com/natefinch/lumberjack>)
for log rotation. lumberjack offers time-based and size-based rotation,
along with log compression, which aligns with the current Synapse log
rotation capabilities. I have successfully tested slog configurations that
integrate with lumberjack.

I believe this proposed logging strategy provides a solid foundation for
the Apache Synapse Go implementation. I welcome your feedback and
suggestions on this proposal.

Thanks,

Thisara Weerakoon

Reply via email to