Skip to content

Log Refactor #14087

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Log Refactor #14087

wants to merge 4 commits into from

Conversation

kasswag11
Copy link

Overview
We propose refactoring the Log utility in org.signal.glide to better align with DDD principles by introducing the following:
A LoggingService interface.
LogTag and LogMessage value objects.
Moving implementation details to the infrastructure layer.
This will decouple logging from domain logic, improve modularity, and enhance testability. During a deep dive into the Signal Android codebase for a university software architecture course, our team identified a tight coupling between domain logic and infrastructure in the current logging mechanism.
The static, global access to logging (SignalGlideCodecs.getLogProvider()) and raw strings for tags/messages make logging less flexible, error-prone, and more complicated to test. It is this idea we are targeting for our refactoring.
Problems Identified
Tight Coupling to static global state (SignalGlideCodecs).
There is no Abstraction between domain logic and infrastructure.
Strongly typed metadata, which reduces clarity and consistency.
Logging Output Loss due to silent fallback EMPTY Provider.
Benefits
Improved separation of concerns.
Consistent and error-resistant metadata handling.
Aligns logging infrastructure with DDD best practices.

We’re happy to submit a Draft Pull Request with this implementation for further discussion if the maintainers are interested. We would love to hear your thoughts.

Proposed Refactor
Abstract Logging Behind a Service Interface
public interface LoggingService {
void logInfo(LogTag tag, LogMessage message);
void logError(LogTag tag, LogMessage message, @nullable Throwable throwable);
}

Introduce Value Objects for Log Metadata

public record LogTag(String value) { }
public record LogMessage(String value) { }

Move the Implementation to the Infrastructure Layer

public class AndroidLoggingService implements LoggingService {
public void logInfo(LogTag tag, LogMessage message) {
SignalGlideCodecs.getLogProvider().i(tag.value(), message.value());
}
public void logError(LogTag tag, LogMessage message, @nullable Throwable t) {
SignalGlideCodecs.getLogProvider().e(tag.value(), message.value(), t);
}
}

Thanks for your time and the great work on Signal

  • Griffin Urban, Seth Clover, Kasson Plummer, Nathan Voung, Lawson Port

Comment on lines +1 to +9
package org.signal.glide.transforms;

public record LogMessage(String value) {
public LogMessage {
if (value == null || value.isBlank()) {
throw new IllegalArgumentException("LogMessage cannot be null or blank");
}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that this PR introduces a new file in Java, while we're in the midst of migrating our codebase to Kotlin. Is there a particular reason we opted for Java here instead of Kotlin?
Would it be possible to implement this new functionality in Kotlin to maintain consistency with our migration efforts?

Comment on lines +1 to +9
package org.signal.glide.transforms;

public record LogTag(String value) {
public LogTag {
if (value == null || value.isBlank()) {
throw new IllegalArgumentException("LogTag cannot be null or blank");
}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

Comment on lines +1 to +10
package org.signal.glide.transforms;

import androidx.annotation.Nullable;

public interface LoggingService {
void logDebug(LogTag tag, LogMessage message);
void logInfo(LogTag tag, LogMessage message);
void logWarn(LogTag tag, LogMessage message);
void logError(LogTag tag, LogMessage message, @Nullable Throwable throwable);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

@mtang-signal
Copy link
Contributor

Hi! Thank you for choosing Signal for your university software architecture course :) . I'm going to caution against opening a pr to change our logging mechanism. Logging is crucial to working on and improving Signal and it is something that works well. A new refactor will be difficult to review meaningfully and still lead to its own specific set of bugs which we want to avoid, given how vital and functional logging is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants