Skip to content

Commit e182b52

Browse files
committed
Initial implementation for the Log class
1 parent 458af40 commit e182b52

File tree

5 files changed

+406
-0
lines changed

5 files changed

+406
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
</manifest>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.github.neboskreb.log4j2.migration;
2+
3+
import androidx.annotation.NonNull;
4+
import androidx.annotation.Nullable;
5+
6+
public interface ILogAdapter {
7+
enum ANDROID_LEVEL {
8+
VERBOSE, DEBUG, INFO, WARN, ERROR, WTF
9+
}
10+
11+
boolean isLoggable(ANDROID_LEVEL androidLevel, @NonNull String tag);
12+
int logIfLoggable(ANDROID_LEVEL androidLevel, @NonNull String tag, @Nullable String msg, @Nullable Throwable tr);
13+
}
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
package com.github.neboskreb.log4j2.migration;
2+
3+
4+
import androidx.annotation.NonNull;
5+
import androidx.annotation.Nullable;
6+
import com.github.neboskreb.log4j2.migration.ILogAdapter.ANDROID_LEVEL;
7+
import com.github.neboskreb.log4j2.migration.log4j2.Log4j2Adapter;
8+
import com.github.neboskreb.log4j2.migration.slf4j.Slf4jAdapter;
9+
10+
import static com.github.neboskreb.log4j2.migration.ILogAdapter.ANDROID_LEVEL.*;
11+
import static java.util.Objects.requireNonNullElse;
12+
13+
/**
14+
* @deprecated DO NOT USE IN NEW CODE. <br>
15+
* BEWARE OF THE PERFORMANCE HIT! <br>
16+
* This class is intended as an emergency patch while migrating your legacy logging to Log4j.
17+
* After having patched your code, migrate it to proper logging as soon as possible.
18+
*/
19+
@Deprecated
20+
@SuppressWarnings("unused")
21+
public final class Log {
22+
private static ILogAdapter adapter = new Slf4jAdapter();
23+
24+
public static void useLog4j2() {
25+
adapter = new Log4j2Adapter();
26+
}
27+
28+
29+
private Log() {
30+
}
31+
32+
/**
33+
* Send a {@link android.util.Log#VERBOSE VERBOSE} log message.
34+
* @param tag Used to identify the source of a log message. It usually identifies
35+
* the class or activity where the log call occurs.
36+
* @param msg The message you would like logged.
37+
* @return A positive value if the message was loggable (see {@link #isLoggable}).
38+
*/
39+
public static int v(@Nullable String tag, @NonNull String msg) {
40+
return log(VERBOSE, tag, msg, null);
41+
}
42+
43+
/**
44+
* Send a {@link android.util.Log#VERBOSE VERBOSE} log message and log the exception.
45+
* @param tag Used to identify the source of a log message. It usually identifies
46+
* the class or activity where the log call occurs.
47+
* @param msg The message you would like logged.
48+
* @param tr An exception to log.
49+
* @return A positive value if the message was loggable (see {@link #isLoggable}).
50+
*/
51+
public static int v(@Nullable String tag, @Nullable String msg, @Nullable Throwable tr) {
52+
return log(VERBOSE, tag, msg, tr);
53+
}
54+
55+
/**
56+
* Send a {@link android.util.Log#DEBUG DEBUG} log message.
57+
* @param tag Used to identify the source of a log message. It usually identifies
58+
* the class or activity where the log call occurs.
59+
* @param msg The message you would like logged.
60+
* @return A positive value if the message was loggable (see {@link #isLoggable}).
61+
*/
62+
public static int d(@Nullable String tag, @NonNull String msg) {
63+
return log(DEBUG, tag, msg, null);
64+
}
65+
66+
/**
67+
* Send a {@link android.util.Log#DEBUG DEBUG} log message and log the exception.
68+
* @param tag Used to identify the source of a log message. It usually identifies
69+
* the class or activity where the log call occurs.
70+
* @param msg The message you would like logged.
71+
* @param tr An exception to log.
72+
* @return A positive value if the message was loggable (see {@link #isLoggable}).
73+
*/
74+
public static int d(@Nullable String tag, @Nullable String msg, @Nullable Throwable tr) {
75+
return log(DEBUG, tag, msg, tr);
76+
}
77+
78+
/**
79+
* Send an {@link android.util.Log#INFO INFO} log message.
80+
* @param tag Used to identify the source of a log message. It usually identifies
81+
* the class or activity where the log call occurs.
82+
* @param msg The message you would like logged.
83+
* @return A positive value if the message was loggable (see {@link #isLoggable}).
84+
*/
85+
public static int i(@Nullable String tag, @NonNull String msg) {
86+
return log(INFO, tag, msg, null);
87+
}
88+
89+
/**
90+
* Send a {@link android.util.Log#INFO INFO} log message and log the exception.
91+
* @param tag Used to identify the source of a log message. It usually identifies
92+
* the class or activity where the log call occurs.
93+
* @param msg The message you would like logged.
94+
* @param tr An exception to log.
95+
*/
96+
public static int i(@Nullable String tag, @Nullable String msg, @Nullable Throwable tr) {
97+
return log(INFO, tag, msg, tr);
98+
}
99+
100+
/**
101+
* Send a {@link android.util.Log#WARN WARN} log message.
102+
* @param tag Used to identify the source of a log message. It usually identifies
103+
* the class or activity where the log call occurs.
104+
* @param msg The message you would like logged.
105+
* @return A positive value if the message was loggable (see {@link #isLoggable}).
106+
*/
107+
public static int w(@Nullable String tag, @NonNull String msg) {
108+
return log(WARN, tag, msg, null);
109+
}
110+
111+
/**
112+
* Send a {@link android.util.Log#WARN WARN} log message and log the exception.
113+
* @param tag Used to identify the source of a log message. It usually identifies
114+
* the class or activity where the log call occurs.
115+
* @param msg The message you would like logged.
116+
* @param tr An exception to log.
117+
* @return A positive value if the message was loggable (see {@link #isLoggable}).
118+
*/
119+
public static int w(@Nullable String tag, @Nullable String msg, @Nullable Throwable tr) {
120+
return log(WARN, tag, msg, tr);
121+
}
122+
123+
/**
124+
* Checks to see whether or not a log for the specified tag is loggable at the specified level.
125+
*
126+
* The default level of any tag is set to INFO. This means that any level above and including
127+
* INFO will be logged. Before you make any calls to a logging method you should check to see
128+
* if your tag should be logged. You can change the default level by setting a system property:
129+
* 'setprop log.tag.&lt;YOUR_LOG_TAG> &lt;LEVEL>'
130+
* Where level is either VERBOSE, DEBUG, INFO, WARN, ERROR, or ASSERT.
131+
* You can also create a local.prop file that with the following in it:
132+
* 'log.tag.&lt;YOUR_LOG_TAG>=&lt;LEVEL>'
133+
* and place that in /data/local.prop.
134+
*
135+
* @param tag The tag to check.
136+
* @param level The level to check.
137+
* @return Whether or not that this is allowed to be logged.
138+
* @throws IllegalArgumentException is thrown if the tag.length() > 23
139+
* for Nougat (7.0) and prior releases (API <= 25), there is no
140+
* tag limit of concern after this API level.
141+
*/
142+
public static boolean isLoggable(@Nullable String tag, int level) {
143+
ANDROID_LEVEL androidLevel = toAndroidLevel(level);
144+
return adapter.isLoggable(androidLevel, nonNullTag(tag));
145+
}
146+
147+
/**
148+
* Send a {@link android.util.Log#WARN WARN} log message and log the exception.
149+
* @param tag Used to identify the source of a log message. It usually identifies
150+
* the class or activity where the log call occurs.
151+
* @param tr An exception to log.
152+
* @return A positive value if the message was loggable (see {@link #isLoggable}).
153+
*/
154+
public static int w(@Nullable String tag, @Nullable Throwable tr) {
155+
return log(WARN, tag, null, tr);
156+
}
157+
158+
/**
159+
* Send an {@link android.util.Log#ERROR ERROR} log message.
160+
* @param tag Used to identify the source of a log message. It usually identifies
161+
* the class or activity where the log call occurs.
162+
* @param msg The message you would like logged.
163+
* @return A positive value if the message was loggable (see {@link #isLoggable}).
164+
*/
165+
public static int e(@Nullable String tag, @NonNull String msg) {
166+
return log(ERROR, tag, msg, null);
167+
}
168+
169+
/**
170+
* Send a {@link android.util.Log#ERROR ERROR} log message and log the exception.
171+
* @param tag Used to identify the source of a log message. It usually identifies
172+
* the class or activity where the log call occurs.
173+
* @param msg The message you would like logged.
174+
* @param tr An exception to log.
175+
* @return A positive value if the message was loggable (see {@link #isLoggable}).
176+
*/
177+
public static int e(@Nullable String tag, @Nullable String msg, @Nullable Throwable tr) {
178+
return log(ERROR, tag, msg, tr);
179+
}
180+
181+
/**
182+
* What a Terrible Failure: Report a condition that should never happen.
183+
* The error will always be logged at level ASSERT with the call stack.
184+
* Depending on system configuration, a report may be added to the
185+
* {@link android.os.DropBoxManager} and/or the process may be terminated
186+
* immediately with an error dialog.
187+
* @param tag Used to identify the source of a log message.
188+
* @param msg The message you would like logged.
189+
* @return A positive value if the message was loggable (see {@link #isLoggable}).
190+
*/
191+
public static int wtf(@Nullable String tag, @Nullable String msg) {
192+
return wtf(tag, msg, null);
193+
}
194+
195+
/**
196+
* Like {@link #wtf(String, String)}, but also writes to the log the full
197+
* call stack.
198+
*/
199+
public static int wtfStack(@Nullable String tag, @Nullable String msg) {
200+
return wtf(tag, msg, new Throwable("StackTrace"));
201+
}
202+
203+
/**
204+
* What a Terrible Failure: Report an exception that should never happen.
205+
* Similar to {@link #wtf(String, String)}, with an exception to log.
206+
* @param tag Used to identify the source of a log message.
207+
* @param tr An exception to log.
208+
* @return A positive value if the message was loggable (see {@link #isLoggable}).
209+
*/
210+
public static int wtf(@Nullable String tag, @NonNull Throwable tr) {
211+
return wtf(tag, null, tr);
212+
}
213+
214+
/**
215+
* What a Terrible Failure: Report an exception that should never happen.
216+
* Similar to {@link #wtf(String, Throwable)}, with a message as well.
217+
* @param tag Used to identify the source of a log message.
218+
* @param msg The message you would like logged.
219+
* @param tr An exception to log. May be null.
220+
* @return A positive value if the message was loggable (see {@link #isLoggable}).
221+
*/
222+
public static int wtf(@Nullable String tag, @Nullable String msg, @Nullable Throwable tr) {
223+
return log(WTF, tag, msg, tr);
224+
}
225+
226+
public static <TerribleFailureHandler> TerribleFailureHandler setWtfHandler(@NonNull TerribleFailureHandler handler) {
227+
throw new UnsupportedOperationException();
228+
}
229+
230+
/**
231+
* Handy function to get a loggable stack trace from a Throwable
232+
233+
* <p>If any of the throwables in the cause chain is an <code>UnknownHostException</code>,
234+
* this returns an empty string.
235+
* @param tr An exception to log.
236+
*/
237+
@NonNull
238+
public static String getStackTraceString(@Nullable Throwable tr) {
239+
return android.util.Log.getStackTraceString(tr);
240+
}
241+
242+
public static int println(int priority, @Nullable String tag, @NonNull String msg) {
243+
throw new UnsupportedOperationException();
244+
}
245+
246+
public static int logToRadioBuffer(int priority, @Nullable String tag, @Nullable String message) {
247+
throw new UnsupportedOperationException();
248+
}
249+
250+
public static int printlns(int bufID, int priority, @Nullable String tag, @NonNull String msg, @Nullable Throwable tr) {
251+
throw new UnsupportedOperationException();
252+
}
253+
254+
255+
256+
257+
private static int log(ANDROID_LEVEL androidLevel, @Nullable String tag, @Nullable String msg, @Nullable Throwable tr) {
258+
return adapter.logIfLoggable(androidLevel, nonNullTag(tag), msg, tr);
259+
}
260+
261+
@NonNull
262+
private static String nonNullTag(@Nullable String tag) {
263+
return requireNonNullElse(tag, "TAG");
264+
}
265+
266+
private static ANDROID_LEVEL toAndroidLevel(int level) {
267+
return switch (level) {
268+
case android.util.Log.VERBOSE -> VERBOSE;
269+
case android.util.Log.DEBUG -> DEBUG;
270+
case android.util.Log.INFO -> INFO;
271+
case android.util.Log.WARN -> WARN;
272+
case android.util.Log.ERROR -> ERROR;
273+
case android.util.Log.ASSERT -> ERROR;
274+
default -> throw new IllegalArgumentException("Unknown log level: " + level);
275+
};
276+
}
277+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.github.neboskreb.log4j2.migration.log4j2;
2+
3+
import androidx.annotation.NonNull;
4+
import androidx.annotation.Nullable;
5+
import com.github.neboskreb.log4j2.migration.ILogAdapter;
6+
import org.apache.logging.log4j.Level;
7+
import org.apache.logging.log4j.LogBuilder;
8+
import org.apache.logging.log4j.LogManager;
9+
import org.apache.logging.log4j.Logger;
10+
11+
public class Log4j2Adapter implements ILogAdapter {
12+
@Override
13+
public boolean isLoggable(ANDROID_LEVEL androidLevel, @NonNull String tag) {
14+
return getLogger(tag).isEnabled(toLog4jLevel(androidLevel));
15+
}
16+
17+
@Override
18+
public int logIfLoggable(ANDROID_LEVEL androidLevel, @NonNull String tag, @Nullable String msg, @Nullable Throwable tr) {
19+
if (msg == null && tr == null) {
20+
return 0;
21+
}
22+
23+
Level level = toLog4jLevel(androidLevel);
24+
Logger logger = getLogger(tag);
25+
if (!logger.isEnabled(level)) {
26+
return 0;
27+
}
28+
29+
LogBuilder builder = logger.atLevel(level);
30+
if (tr != null) {
31+
builder.withThrowable(tr);
32+
}
33+
if (msg != null) {
34+
builder.log(msg);
35+
} else {
36+
builder.log();
37+
}
38+
39+
return 1;
40+
}
41+
42+
public Level toLog4jLevel(ANDROID_LEVEL androidLevel) {
43+
return switch (androidLevel) {
44+
case VERBOSE -> Level.TRACE;
45+
case DEBUG -> Level.DEBUG;
46+
case INFO -> Level.INFO;
47+
case WARN -> Level.WARN;
48+
case ERROR -> Level.ERROR;
49+
case WTF -> Level.FATAL;
50+
};
51+
}
52+
53+
public Logger getLogger(@NonNull String tag) {
54+
// No `synchronized` needed here as Log4j2 logger registry is thread-safe
55+
return LogManager.getLogger(tag);
56+
}
57+
}

0 commit comments

Comments
 (0)