aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWyatt Hepler <hepler@google.com>2022-01-25 10:43:06 -0800
committerCQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-04-04 17:24:18 +0000
commitd14e858ca630583416b8c54b49868bc9e5b338c1 (patch)
tree05faccdcf30e33d4d79a84fd43a4866444f1c8ed
parent507dcae2bf64868ae2db9c14fe90b0607ddb96e3 (diff)
downloadpigweed-d14e858ca630583416b8c54b49868bc9e5b338c1.tar.gz
pw_rpc: Restore Java client logging
- Create dev.pigweed.pw_log.Logger to support logging to either a FluentLogger or the Android logger. - Restore the pw_rpc Java client logs using dev.pigweed.pw_log.Logger. Change-Id: I73a658deed6c0da3c6d9c8157f798c56dfbf9f10 Fixed: 611 Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/81420 Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com> Reviewed-by: Ted Pudlik <tpudlik@google.com> Reviewed-by: Keir Mierle <keir@google.com> Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
-rw-r--r--pw_log/Android.bp10
-rw-r--r--pw_log/docs.rst11
-rw-r--r--pw_log/java/android_main/dev/pigweed/pw_log/Logger.java110
-rw-r--r--pw_log/java/main/dev/pigweed/pw_log/BUILD.bazel25
-rw-r--r--pw_log/java/main/dev/pigweed/pw_log/Logger.java71
-rw-r--r--pw_rpc/Android.bp1
-rw-r--r--pw_rpc/java/main/dev/pigweed/pw_rpc/BUILD.bazel2
-rw-r--r--pw_rpc/java/main/dev/pigweed/pw_rpc/Client.java38
-rw-r--r--pw_rpc/java/main/dev/pigweed/pw_rpc/RpcManager.java18
-rw-r--r--pw_rpc/java/main/dev/pigweed/pw_rpc/StreamObserverCall.java9
10 files changed, 259 insertions, 36 deletions
diff --git a/pw_log/Android.bp b/pw_log/Android.bp
index 64a602024..9b5bb34f9 100644
--- a/pw_log/Android.bp
+++ b/pw_log/Android.bp
@@ -19,4 +19,12 @@ cc_library {
export_include_dirs: [
"public",
],
-} \ No newline at end of file
+}
+
+java_library {
+ name: "pw_log_android_java",
+ host_supported: true,
+ srcs: ["java/android_main/dev/pigweed/pw_log/*.java"],
+ visibility: ["//visibility:public"],
+ sdk_version: "current",
+}
diff --git a/pw_log/docs.rst b/pw_log/docs.rst
index 6c30cd8ab..b3eac4376 100644
--- a/pw_log/docs.rst
+++ b/pw_log/docs.rst
@@ -412,3 +412,14 @@ argument to each macro call seemed like too much. On the other hand, flags are
something that are typically added on a per-log-statement basis, and is why the
flags are added on a per-call basis (though hidden through the high-level
macros).
+
+--------------
+pw_log in Java
+--------------
+``pw_log`` provides a thin Java logging class that uses Google's `Flogger
+<https://google.github.io/flogger/>`_ API. The purpose of this wrapper is to
+support logging on platforms that do not support Flogger. The main
+implementation in ``pw_log/java/main`` simply wraps a
+``com.google.common.flogger.FluentLogger``. An implementation that logs to
+Android's ``android.util.Log`` instead is provided in
+``pw_log/java/android_main``.
diff --git a/pw_log/java/android_main/dev/pigweed/pw_log/Logger.java b/pw_log/java/android_main/dev/pigweed/pw_log/Logger.java
new file mode 100644
index 000000000..01d47aba2
--- /dev/null
+++ b/pw_log/java/android_main/dev/pigweed/pw_log/Logger.java
@@ -0,0 +1,110 @@
+// Copyright 2022 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package dev.pigweed.pw_log;
+
+import android.util.Log;
+import java.util.logging.Level;
+
+/**
+ * Partial implementation of the com.google.common.flogger.FluentLogger API that
+ * logs to android.util.Log.
+ */
+public final class Logger {
+ private final String tag;
+
+ public final class AndroidLogApi {
+ private final int level;
+
+ private Throwable cause = null;
+
+ private AndroidLogApi(Level level) {
+ switch (level) {
+ case Level.FINEST:
+ case Level.FINER:
+ this.level = Log.VERBOSE;
+ break;
+ case Level.FINE:
+ case Level.CONFIG:
+ this.level = Log.DEBUG;
+ break;
+ case Level.INFO:
+ this.level = Log.INFO;
+ break;
+ case Level.WARNING:
+ this.level = Log.WARN;
+ break;
+ case Level.SEVERE:
+ this.level = Log.ERROR;
+ break;
+ }
+ }
+
+ public AndroidLogApi withCause(Throwable casue) {
+ this.cause = cause;
+ }
+
+ public void log(String message) {
+ if (cause != null) {
+ message = String.format("%s: %s", cause, message);
+ }
+
+ Log.println(level, tag, message);
+ }
+
+ public void log(String message, Object... args) {
+ log(String.format(message, args));
+ }
+ }
+
+ public static Logger forClass(Class<?> enclosingClass) {
+ return new Logger(enclosingClass.getSimpleName());
+ }
+
+ private Logger(String tag) {
+ this.tag = tag;
+ }
+
+ public AndroidLogApi at(Level level) {
+ return new AndroidLogApi(level);
+ }
+
+ public AndroidLogApi atSevere() {
+ return at(Level.SEVERE);
+ }
+
+ public AndroidLogApi atWarning() {
+ return at(Level.WARNING);
+ }
+
+ public AndroidLogApi atInfo() {
+ return at(Level.INFO);
+ }
+
+ public AndroidLogApi atConfig() {
+ return at(Level.CONFIG);
+ }
+
+ public AndroidLogApi atFine() {
+ return at(Level.FINE);
+ }
+
+ public AndroidLogApi atFiner() {
+ return at(Level.FINER);
+ }
+
+ public AndroidLogApi atFinest() {
+ return at(Level.FINEST);
+ }
+}
diff --git a/pw_log/java/main/dev/pigweed/pw_log/BUILD.bazel b/pw_log/java/main/dev/pigweed/pw_log/BUILD.bazel
new file mode 100644
index 000000000..8ebacb05a
--- /dev/null
+++ b/pw_log/java/main/dev/pigweed/pw_log/BUILD.bazel
@@ -0,0 +1,25 @@
+# Copyright 2022 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+# Logging API that maps to Google's Flogger (https://google.github.io/flogger/),
+# or an alternate API if Flogger is not supported.
+
+java_library(
+ name = "pw_log",
+ srcs = ["Logger.java"],
+ visibility = ["//visibility:public"],
+ deps = [
+ "@maven//:com_google_flogger_flogger",
+ ],
+)
diff --git a/pw_log/java/main/dev/pigweed/pw_log/Logger.java b/pw_log/java/main/dev/pigweed/pw_log/Logger.java
new file mode 100644
index 000000000..f1ba7449c
--- /dev/null
+++ b/pw_log/java/main/dev/pigweed/pw_log/Logger.java
@@ -0,0 +1,71 @@
+// Copyright 2022 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package dev.pigweed.pw_log;
+
+import com.google.common.flogger.FluentLogger;
+import java.util.logging.Level;
+
+/**
+ * Partial implementation of the com.google.common.flogger.FluentLogger API that
+ * wraps a FluentLogger instance.
+ *
+ * This class is used instead of directly logging to FluentLogger to support
+ * swapping the implementation on systems that don't support FluentLogger (i.e.
+ * Android).
+ */
+@SuppressWarnings("FloggerSplitLogStatement")
+public final class Logger {
+ private final FluentLogger wrappedLogger;
+
+ public static Logger forClass(Class<?> enclosingClass) {
+ return new Logger(FluentLogger.forEnclosingClass());
+ }
+
+ private Logger(FluentLogger fluentLogger) {
+ this.wrappedLogger = fluentLogger;
+ }
+
+ public FluentLogger.Api at(Level level) {
+ return wrappedLogger.at(level);
+ }
+
+ public FluentLogger.Api atSevere() {
+ return at(Level.SEVERE);
+ }
+
+ public FluentLogger.Api atWarning() {
+ return at(Level.WARNING);
+ }
+
+ public FluentLogger.Api atInfo() {
+ return at(Level.INFO);
+ }
+
+ public FluentLogger.Api atConfig() {
+ return at(Level.CONFIG);
+ }
+
+ public FluentLogger.Api atFine() {
+ return at(Level.FINE);
+ }
+
+ public FluentLogger.Api atFiner() {
+ return at(Level.FINER);
+ }
+
+ public FluentLogger.Api atFinest() {
+ return at(Level.FINEST);
+ }
+}
diff --git a/pw_rpc/Android.bp b/pw_rpc/Android.bp
index aeca94b0f..9bb863871 100644
--- a/pw_rpc/Android.bp
+++ b/pw_rpc/Android.bp
@@ -25,6 +25,7 @@ java_library {
"guava",
"jsr305",
"libprotobuf-java-lite",
+ "pw_log_android_java",
],
plugins: ["auto_value_plugin"],
sdk_version: "current",
diff --git a/pw_rpc/java/main/dev/pigweed/pw_rpc/BUILD.bazel b/pw_rpc/java/main/dev/pigweed/pw_rpc/BUILD.bazel
index 5f834a029..4747b7f86 100644
--- a/pw_rpc/java/main/dev/pigweed/pw_rpc/BUILD.bazel
+++ b/pw_rpc/java/main/dev/pigweed/pw_rpc/BUILD.bazel
@@ -36,11 +36,11 @@ java_library(
],
visibility = ["//visibility:public"],
deps = [
+ "//pw_log/java/main/dev/pigweed/pw_log",
"//pw_rpc:packet_proto_java_lite",
"//third_party/google_auto:value",
"@com_google_protobuf//java/lite",
"@maven//:com_google_code_findbugs_jsr305",
- "@maven//:com_google_flogger_flogger",
"@maven//:com_google_guava_guava",
],
)
diff --git a/pw_rpc/java/main/dev/pigweed/pw_rpc/Client.java b/pw_rpc/java/main/dev/pigweed/pw_rpc/Client.java
index ea3f7df9f..f4d187351 100644
--- a/pw_rpc/java/main/dev/pigweed/pw_rpc/Client.java
+++ b/pw_rpc/java/main/dev/pigweed/pw_rpc/Client.java
@@ -14,10 +14,10 @@
package dev.pigweed.pw_rpc;
-// import com.google.common.flogger.FluentLogger;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageLite;
+import dev.pigweed.pw_log.Logger;
import dev.pigweed.pw_rpc.internal.Packet.PacketType;
import dev.pigweed.pw_rpc.internal.Packet.RpcPacket;
import java.nio.ByteBuffer;
@@ -33,8 +33,7 @@ import javax.annotation.Nullable;
* through the processPacket function.
*/
public class Client {
- // TODO(pwbug/611): Restore logging without a mandatory Flogger dependency.
- // private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+ private static final Logger logger = Logger.forClass(Client.class);
private final Map<Integer, Channel> channels;
private final Map<Integer, Service> services;
@@ -81,17 +80,17 @@ public class Client {
return create(channels, services, (rpc) -> new StreamObserver<MessageLite>() {
@Override
public void onNext(MessageLite value) {
- // logger.atFine().log("%s received response: %s", rpc, value);
+ logger.atFine().log("%s received response: %s", rpc, value);
}
@Override
public void onCompleted(Status status) {
- // logger.atInfo().log("%s completed with status %s", rpc, status);
+ logger.atInfo().log("%s completed with status %s", rpc, status);
}
@Override
public void onError(Status status) {
- // logger.atWarning().log("%s terminated with error %s", rpc, status);
+ logger.atWarning().log("%s terminated with error %s", rpc, status);
}
});
}
@@ -167,31 +166,30 @@ public class Client {
try {
packet = RpcPacket.parseFrom(data, ExtensionRegistryLite.getEmptyRegistry());
} catch (InvalidProtocolBufferException e) {
- // logger.atWarning().withCause(e).log("Failed to decode packet");
+ logger.atWarning().withCause(e).log("Failed to decode packet");
return false;
}
if (packet.getChannelId() == 0 || packet.getServiceId() == 0 || packet.getMethodId() == 0) {
- // logger.atWarning().log("Received corrupt packet with unset IDs");
+ logger.atWarning().log("Received corrupt packet with unset IDs");
return false;
}
// Packets for the server use even type values.
if (packet.getTypeValue() % 2 == 0) {
- // logger.atFine().log("Ignoring %s packet for server", packet.getType().name());
+ logger.atFine().log("Ignoring %s packet for server", packet.getType().name());
return false;
}
Channel channel = channels.get(packet.getChannelId());
if (channel == null) {
- // logger.atWarning().log(
- // "Received packet for unrecognized channel %d", packet.getChannelId());
+ logger.atWarning().log("Received packet for unrecognized channel %d", packet.getChannelId());
return false;
}
PendingRpc rpc = lookupRpc(channel, packet);
if (rpc == null) {
- // logger.atInfo().log("Ignoring packet for unknown service method");
+ logger.atInfo().log("Ignoring packet for unknown service method");
sendError(channel, packet, Status.NOT_FOUND);
return true; // true since the packet was handled, even though it was invalid.
}
@@ -200,8 +198,8 @@ public class Client {
StreamObserverCall<?, ?> call =
packet.getType().equals(PacketType.SERVER_STREAM) ? rpcs.getPending(rpc) : rpcs.clear(rpc);
if (call == null) {
- // logger.atInfo().log(
- // "Ignoring packet for RPC (%s) that isn't pending. Pending RPCs are: %s", rpc, rpcs);
+ logger.atInfo().log(
+ "Ignoring packet for RPC (%s) that isn't pending. Pending RPCs are: %s", rpc, rpcs);
sendError(channel, packet, Status.FAILED_PRECONDITION);
return true;
}
@@ -209,7 +207,7 @@ public class Client {
switch (packet.getType()) {
case SERVER_ERROR:
Status status = decodeStatus(packet);
- // logger.atWarning().log("RPC %s failed with error %s", rpc, status);
+ logger.atWarning().log("RPC %s failed with error %s", rpc, status);
call.onError(status);
break;
case RESPONSE:
@@ -223,8 +221,8 @@ public class Client {
call.onNext(packet.getPayload());
break;
default:
- // logger.atWarning().log(
- // "Unexpected PacketType %d for RPC %s", packet.getType().getNumber(), rpc);
+ logger.atWarning().log(
+ "Unexpected PacketType %d for RPC %s", packet.getType().getNumber(), rpc);
}
return true;
@@ -234,7 +232,7 @@ public class Client {
try {
channel.send(Packets.error(packet, status));
} catch (ChannelOutputException e) {
- // logger.atWarning().withCause(e).log("Failed to send error packet");
+ logger.atWarning().withCause(e).log("Failed to send error packet");
}
}
@@ -254,8 +252,8 @@ public class Client {
private static Status decodeStatus(RpcPacket packet) {
Status status = Status.fromCode(packet.getStatus());
if (status == null) {
- // logger.atWarning().log(
- // "Illegal status code %d in packet; using Status.UNKNOWN ", packet.getStatus());
+ logger.atWarning().log(
+ "Illegal status code %d in packet; using Status.UNKNOWN ", packet.getStatus());
return Status.UNKNOWN;
}
return status;
diff --git a/pw_rpc/java/main/dev/pigweed/pw_rpc/RpcManager.java b/pw_rpc/java/main/dev/pigweed/pw_rpc/RpcManager.java
index 12e6db1a6..2f8b8699d 100644
--- a/pw_rpc/java/main/dev/pigweed/pw_rpc/RpcManager.java
+++ b/pw_rpc/java/main/dev/pigweed/pw_rpc/RpcManager.java
@@ -14,16 +14,16 @@
package dev.pigweed.pw_rpc;
-// import com.google.common.flogger.FluentLogger;
import com.google.protobuf.MessageLite;
+import dev.pigweed.pw_log.Logger;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
/** Tracks the state of service method invocations. */
public class RpcManager {
- // TODO(pwbug/611): Restore logging without a mandatory Flogger dependency.
- // private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+ private static final Logger logger = Logger.forClass(RpcManager.class);
+
private final Map<PendingRpc, StreamObserverCall<?, ?>> pending = new HashMap<>();
/**
@@ -37,7 +37,7 @@ public class RpcManager {
public synchronized StreamObserverCall<?, ?> start(
PendingRpc rpc, StreamObserverCall<?, ?> call, @Nullable MessageLite payload)
throws ChannelOutputException {
- // logger.atFine().log("Start %s", rpc);
+ logger.atFine().log("Start %s", rpc);
rpc.channel().send(Packets.request(rpc, payload));
return pending.put(rpc, call);
}
@@ -51,12 +51,12 @@ public class RpcManager {
@Nullable
public synchronized StreamObserverCall<?, ?> open(
PendingRpc rpc, StreamObserverCall<?, ?> call, @Nullable MessageLite payload) {
- // logger.atFine().log("Open %s", rpc);
+ logger.atFine().log("Open %s", rpc);
try {
rpc.channel().send(Packets.request(rpc, payload));
} catch (ChannelOutputException e) {
- // logger.atFine().withCause(e).log(
- // "Ignoring error opening %s; listening for unrequested responses", rpc);
+ logger.atFine().withCause(e).log(
+ "Ignoring error opening %s; listening for unrequested responses", rpc);
}
return pending.put(rpc, call);
}
@@ -67,7 +67,7 @@ public class RpcManager {
throws ChannelOutputException {
StreamObserverCall<?, ?> call = pending.remove(rpc);
if (call != null) {
- // logger.atFine().log("Cancel %s", rpc);
+ logger.atFine().log("Cancel %s", rpc);
rpc.channel().send(Packets.cancel(rpc));
}
return call;
@@ -97,7 +97,7 @@ public class RpcManager {
public synchronized StreamObserverCall<?, ?> clear(PendingRpc rpc) {
StreamObserverCall<?, ?> call = pending.remove(rpc);
if (call != null) {
- // logger.atFine().log("Clear %s", rpc);
+ logger.atFine().log("Clear %s", rpc);
}
return call;
}
diff --git a/pw_rpc/java/main/dev/pigweed/pw_rpc/StreamObserverCall.java b/pw_rpc/java/main/dev/pigweed/pw_rpc/StreamObserverCall.java
index f59d1518b..537362c6c 100644
--- a/pw_rpc/java/main/dev/pigweed/pw_rpc/StreamObserverCall.java
+++ b/pw_rpc/java/main/dev/pigweed/pw_rpc/StreamObserverCall.java
@@ -14,11 +14,11 @@
package dev.pigweed.pw_rpc;
-// import com.google.common.flogger.FluentLogger;
import com.google.common.util.concurrent.AbstractFuture;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageLite;
+import dev.pigweed.pw_log.Logger;
import dev.pigweed.pw_rpc.Call.ClientStreaming;
import java.util.function.Consumer;
import javax.annotation.Nullable;
@@ -35,8 +35,7 @@ import javax.annotation.Nullable;
*/
class StreamObserverCall<RequestT extends MessageLite, ResponseT extends MessageLite>
implements ClientStreaming<RequestT> {
- // TODO(pwbug/611): Restore logging without a mandatory Flogger dependency.
- // private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+ private static final Logger logger = Logger.forClass(StreamObserverCall.class);
private final RpcManager rpcs;
private final PendingRpc rpc;
@@ -258,8 +257,8 @@ class StreamObserverCall<RequestT extends MessageLite, ResponseT extends Message
try {
return (ResponseT) rpc.method().decodeResponsePayload(payload);
} catch (InvalidProtocolBufferException e) {
- // logger.atWarning().withCause(e).log(
- // "Failed to decode response for method %s; skipping packet", rpc.method().name());
+ logger.atWarning().withCause(e).log(
+ "Failed to decode response for method %s; skipping packet", rpc.method().name());
return null;
}
}