1+ /*
2+ * Copyright 2026 Google LLC
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+ package com .google .cloud .pubsub .v1 ;
18+
19+ import com .google .pubsub .v1 .PubsubMessage ;
20+ import java .util .logging .Level ;
21+ import java .util .logging .Logger ;
22+
23+ public final class LoggingUtil {
24+ // Instantiate all loggers as static final fields to maintain strong references
25+
26+ private static final Logger slowAckLogger = Logger .getLogger ("slow-ack" );
27+ private static final Logger callbackDeliveryLogger = Logger .getLogger ("callback-delivery" );
28+ private static final Logger expiryLogger = Logger .getLogger ("expiry" );
29+ private static final Logger callbackExceptionsLogger = Logger .getLogger ("callback-exceptions" );
30+ private static final Logger ackBatchLogger = Logger .getLogger ("ack-batch" );
31+ private static final Logger subscriberFlowControlLogger =
32+ Logger .getLogger ("subscriber-flow-control" );
33+ private static final Logger ackNackLogger = Logger .getLogger ("ack-nack" );
34+ private static final Logger publishBatchLogger = Logger .getLogger ("publish-batch" );
35+ private static final Logger subscriberStreamsLogger = Logger .getLogger ("subscriber-streams" );
36+
37+ public enum SubSystem {
38+ SLOW_ACK (slowAckLogger ),
39+ CALLBACK_DELIVERY (callbackDeliveryLogger ),
40+ EXPIRY (expiryLogger ),
41+ CALLBACK_EXCEPTIONS (callbackExceptionsLogger ),
42+ ACK_BATCH (ackBatchLogger ),
43+ SUBSCRIBER_FLOW_CONTROL (subscriberFlowControlLogger ),
44+ ACK_NACK (ackNackLogger ),
45+ PUBLISH_BATCH (publishBatchLogger ),
46+ SUBSCRIBER_STREAMS (subscriberStreamsLogger );
47+
48+ private final Logger logger ;
49+
50+ SubSystem (Logger logger ) {
51+ this .logger = logger ;
52+ }
53+
54+ public Logger getLogger () {
55+ return logger ;
56+ }
57+ }
58+
59+ public LoggingUtil () {}
60+
61+ private String getSubscriptionLogPrefix (
62+ PubsubMessageWrapper messageWrapper , String ackId , boolean exactlyOnceDeliveryEnabled ) {
63+ if (messageWrapper == null || messageWrapper .getPubsubMessage () == null ) {
64+ return " Ack ID: "
65+ + ackId
66+ + ", Exactly Once Delivery: "
67+ + exactlyOnceDeliveryEnabled
68+ + " (Message details not available)" ;
69+ }
70+
71+ PubsubMessage message = messageWrapper .getPubsubMessage ();
72+ String messageId = message .getMessageId ();
73+ String orderingKey = message .getOrderingKey ();
74+
75+ StringBuilder sb = new StringBuilder ();
76+ sb .append ("Message ID: " ).append (messageId );
77+ sb .append (", Ack ID: " ).append (ackId );
78+ if (orderingKey != null && !orderingKey .isEmpty ()) {
79+ sb .append (", Ordering Key: " ).append (orderingKey );
80+ }
81+ sb .append (", Exactly Once Delivery: " ).append (exactlyOnceDeliveryEnabled );
82+ return sb .toString ();
83+ }
84+
85+ private String getPublisherLogPrefix (PubsubMessageWrapper messageWrapper ) {
86+ if (messageWrapper == null || messageWrapper .getPubsubMessage () == null ) {
87+ return " (Message details not available)" ;
88+ }
89+
90+ PubsubMessage message = messageWrapper .getPubsubMessage ();
91+ String messageId = message .getMessageId ();
92+ String orderingKey = message .getOrderingKey ();
93+
94+ StringBuilder sb = new StringBuilder ();
95+ sb .append ("Message ID: " ).append (messageId );
96+ if (orderingKey != null && !orderingKey .isEmpty ()) {
97+ sb .append (", Ordering Key: " ).append (orderingKey );
98+ }
99+ return sb .toString ();
100+ }
101+
102+ public void logSubscriber (
103+ SubSystem subSystem ,
104+ Level level ,
105+ String msg ,
106+ PubsubMessageWrapper messageWrapper ,
107+ String ackId ,
108+ boolean exactlyOnceDeliveryEnabled ) {
109+ Logger logger = subSystem .getLogger ();
110+ if (logger .isLoggable (level )) {
111+ String prefix = getSubscriptionLogPrefix (messageWrapper , ackId , exactlyOnceDeliveryEnabled );
112+ logger .log (level , prefix + " - " + msg );
113+ }
114+ }
115+
116+ public void logSubscriberWithThrowable (
117+ SubSystem subSystem ,
118+ Level level ,
119+ String msg ,
120+ PubsubMessageWrapper messageWrapper ,
121+ String ackId ,
122+ boolean exactlyOnceDeliveryEnabled ,
123+ Throwable throwable ) {
124+ Logger logger = subSystem .getLogger ();
125+ if (logger .isLoggable (level )) {
126+ String prefix = getSubscriptionLogPrefix (messageWrapper , ackId , exactlyOnceDeliveryEnabled );
127+ logger .log (level , prefix + " - " + msg , throwable );
128+ }
129+ }
130+
131+ public void logPublisher (
132+ SubSystem subSystem , Level level , String msg , PubsubMessageWrapper messageWrapper ) {
133+ Logger logger = subSystem .getLogger ();
134+ if (logger .isLoggable (level )) {
135+ String prefix = getPublisherLogPrefix (messageWrapper );
136+ logger .log (level , prefix + " - " + msg );
137+ }
138+ }
139+
140+ public void logEvent (SubSystem subSystem , Level level , String msg , Object ... params ) {
141+ Logger logger = subSystem .getLogger ();
142+ if (logger .isLoggable (level )) {
143+ logger .log (level , msg , params );
144+ }
145+ }
146+ }
0 commit comments