diff --git a/.pubnub.yml b/.pubnub.yml
index a327510cd6..72a596f204 100644
--- a/.pubnub.yml
+++ b/.pubnub.yml
@@ -1,9 +1,9 @@
name: kotlin
-version: 10.5.8
+version: 10.6.0
schema: 1
scm: github.com/pubnub/kotlin
files:
- - build/libs/pubnub-kotlin-10.5.8-all.jar
+ - build/libs/pubnub-kotlin-10.6.0-all.jar
sdks:
-
type: library
@@ -23,8 +23,8 @@ sdks:
-
distribution-type: library
distribution-repository: maven
- package-name: pubnub-kotlin-10.5.8
- location: https://repo.maven.apache.org/maven2/com/pubnub/pubnub-kotlin/10.5.8/pubnub-kotlin-10.5.8.jar
+ package-name: pubnub-kotlin-10.6.0
+ location: https://repo.maven.apache.org/maven2/com/pubnub/pubnub-kotlin/10.6.0/pubnub-kotlin-10.6.0.jar
supported-platforms:
supported-operating-systems:
Android:
@@ -121,6 +121,15 @@ sdks:
license-url: https://www.apache.org/licenses/LICENSE-2.0.txt
is-required: Required
changelog:
+ - date: 2025-09-11
+ version: v10.6.0
+ changes:
+ - type: feature
+ text: "Added structured log statements throughout the system in transport layer, crypto module, serialization, API calls, etc."
+ - type: feature
+ text: "Added deprecation warning for logVerbosity and httpLoggingInterceptor config params. For logging configuration we advise using SLF4J implementation lib like logback or log4j2 and their config capabilities."
+ - type: feature
+ text: "Added new config property called customLoggers, which can bu used when customer needs can not be implemented using configuration options of SLF4J implementation libs like logback or log4j2."
- date: 2025-08-06
version: v10.5.8
changes:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a282d48615..1556e0a38a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## v10.6.0
+September 11 2025
+
+#### Added
+- Added structured log statements throughout the system in transport layer, crypto module, serialization, API calls, etc.
+- Added deprecation warning for logVerbosity and httpLoggingInterceptor config params. For logging configuration we advise using SLF4J implementation lib like logback or log4j2 and their config capabilities.
+- Added new config property called customLoggers, which can bu used when customer needs can not be implemented using configuration options of SLF4J implementation libs like logback or log4j2.
+
## v10.5.8
August 06 2025
diff --git a/README.md b/README.md
index eb1108be8a..db825345c4 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ You will need the publish and subscribe keys to authenticate your app. Get your
com.pubnub
pubnub-kotlin
- 10.5.8
+ 10.6.0
```
diff --git a/gradle.properties b/gradle.properties
index 9b729069a8..86bedca76b 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -18,7 +18,7 @@ RELEASE_SIGNING_ENABLED=true
SONATYPE_HOST=DEFAULT
SONATYPE_AUTOMATIC_RELEASE=false
GROUP=com.pubnub
-VERSION_NAME=10.5.8
+VERSION_NAME=10.6.0
POM_PACKAGING=jar
POM_NAME=PubNub SDK
diff --git a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/PNConfiguration.kt b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/PNConfiguration.kt
index 7330321ce2..a499fc9180 100644
--- a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/PNConfiguration.kt
+++ b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/PNConfiguration.kt
@@ -4,6 +4,7 @@ import com.pubnub.api.UserId
import com.pubnub.api.crypto.CryptoModule
import com.pubnub.api.enums.PNHeartbeatNotificationOptions
import com.pubnub.api.enums.PNLogVerbosity
+import com.pubnub.api.logging.CustomLogger
import com.pubnub.api.retry.RetryConfiguration
import okhttp3.Authenticator
import okhttp3.CertificatePinner
@@ -91,6 +92,13 @@ interface PNConfiguration : com.pubnub.api.v2.PNConfiguration {
/**
* Set to [PNLogVerbosity.BODY] to enable logging of network traffic, otherwise se to [PNLogVerbosity.NONE].
*/
+ @Deprecated(
+ message = "LogVerbosity setting is deprecated and will be removed in future versions. " +
+ "For logging configuration:\n" +
+ "1. Use an SLF4J implementation (recommended)\n" +
+ "2. Or implement CustomLogger interface and set via customLoggers property",
+ level = DeprecationLevel.WARNING
+ )
val logVerbosity: PNLogVerbosity
/**
@@ -248,6 +256,10 @@ interface PNConfiguration : com.pubnub.api.v2.PNConfiguration {
*
* @see [HttpLoggingInterceptor]
*/
+ @Deprecated(
+ message = "This setting is deprecated. Use customLoggers instead",
+ level = DeprecationLevel.WARNING
+ )
val httpLoggingInterceptor: HttpLoggingInterceptor?
/**
@@ -301,6 +313,12 @@ interface PNConfiguration : com.pubnub.api.v2.PNConfiguration {
*/
val managePresenceListManually: Boolean
+ /**
+ * Custom loggers list for creating additional logger instances.
+ * Use it if your slf4j implementation like logback, log4j2, etc. can't meet your specific logging requirements.
+ */
+ val customLoggers: List?
+
override fun build(): PNConfiguration
override fun setUserId(userId: UserId): Builder
@@ -337,6 +355,13 @@ interface PNConfiguration : com.pubnub.api.v2.PNConfiguration {
/**
* Set to [PNLogVerbosity.BODY] to enable logging of network traffic, otherwise se to [PNLogVerbosity.NONE].
*/
+ @Deprecated(
+ message = "LogVerbosity setting is deprecated and will be removed in future versions. " +
+ "For logging configuration:\n" +
+ "1. Use an SLF4J implementation (recommended)\n" +
+ "2. Or implement CustomLogger interface and set via customLoggers property",
+ level = DeprecationLevel.WARNING
+ )
fun logVerbosity(logVerbosity: PNLogVerbosity): Builder
/**
@@ -479,6 +504,10 @@ interface PNConfiguration : com.pubnub.api.v2.PNConfiguration {
*
* @see [HttpLoggingInterceptor]
*/
+ @Deprecated(
+ message = "This setting is deprecated. Use customLoggers instead",
+ level = DeprecationLevel.WARNING
+ )
fun httpLoggingInterceptor(httpLoggingInterceptor: HttpLoggingInterceptor?): Builder
/**
@@ -533,6 +562,12 @@ interface PNConfiguration : com.pubnub.api.v2.PNConfiguration {
* @see PNConfigurationImpl.heartbeatInterval
*/
fun managePresenceListManually(managePresenceListManually: Boolean): Builder
+
+ /**
+ * Custom loggers list for creating additional logger instances.
+ * Use it if your slf4j implementation like logback, log4j2, etc. can't meet your specific logging requirements.
+ */
+ fun customLoggers(customLoggers: List?): Builder
}
}
diff --git a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/LoggingIntegrationTest.java b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/LoggingIntegrationTest.java
new file mode 100644
index 0000000000..e183f1ec6b
--- /dev/null
+++ b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/LoggingIntegrationTest.java
@@ -0,0 +1,105 @@
+package com.pubnub.api.integration;
+
+import com.pubnub.api.PubNubException;
+import com.pubnub.api.UserId;
+import com.pubnub.api.integration.util.BaseIntegrationTest;
+import com.pubnub.api.integration.util.CustomLoggerTestImpl;
+import com.pubnub.api.integration.util.ITTestConfig;
+import com.pubnub.api.integration.util.RandomGenerator;
+import com.pubnub.api.java.PubNub;
+import com.pubnub.api.java.v2.PNConfiguration;
+import com.pubnub.api.logging.LogMessageContent;
+import com.pubnub.api.logging.LogMessageType;
+import org.aeonbits.owner.ConfigFactory;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.UUID;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class LoggingIntegrationTest extends BaseIntegrationTest {
+ final ITTestConfig itTestConfig = ConfigFactory.create(ITTestConfig.class, System.getenv());
+
+ @Test
+ public void testCanLogMessagesUsingCustomLogger() throws PubNubException, InterruptedException {
+ // Clear any previous messages
+ CustomLoggerTestImpl.clear();
+
+ String expectedUuid = UUID.randomUUID().toString();
+ String expectedChannel = "test-channel-" + RandomGenerator.newValue(8);
+
+ PNConfiguration.Builder configBuilder = PNConfiguration.builder(
+ new UserId(expectedUuid),
+ itTestConfig.subscribeKey()
+ );
+ configBuilder.publishKey(itTestConfig.publishKey());
+ configBuilder.customLoggers(Collections.singletonList(new CustomLoggerTestImpl()));
+
+ PubNub pubNub = PubNub.create(configBuilder.build());
+
+ // Publish a message to generate logs
+ pubNub.publish()
+ .channel(expectedChannel)
+ .message(generatePayload())
+ .customMessageType("myType")
+ .sync();
+
+ // Verify logging
+ assertFalse("Should have received string messages", CustomLoggerTestImpl.stringMessages.isEmpty());
+ assertFalse("Should have received LogMessage objects", CustomLoggerTestImpl.logMessages.isEmpty());
+
+ // Verify content - string messages
+ assertTrue(
+ "Should have called publish on the expected channel",
+ CustomLoggerTestImpl.stringMessages.stream().anyMatch(msg ->
+ msg.contains("PublishEndpoint") && msg.contains(expectedChannel)
+ )
+ );
+
+ assertTrue(
+ "Should have called publish on the expected channel",
+ CustomLoggerTestImpl.stringMessages.stream().anyMatch(msg ->
+ msg.contains("NetworkRequest") && msg.contains(expectedChannel)
+ )
+ );
+
+ assertTrue(
+ "Should have called publish on the expected channel",
+ CustomLoggerTestImpl.stringMessages.stream().anyMatch(msg ->
+ msg.contains("NetworkResponse") && msg.contains(expectedChannel)
+ )
+ );
+
+ // Verify content - LogMessage objects
+ assertTrue(
+ "Should have called publish on the expected channel",
+ CustomLoggerTestImpl.logMessages.stream().anyMatch(msg ->
+ msg.getType() == LogMessageType.OBJECT &&
+ msg.getLocation().contains("PublishEndpoint") &&
+ (msg.getMessage() instanceof LogMessageContent.Object) &&
+ expectedChannel.equals(((LogMessageContent.Object) msg.getMessage()).getMessage().get("channel"))
+ )
+ );
+
+ assertTrue(
+ "Should have called publish API. LogMessage type should be NETWORK_REQUEST",
+ CustomLoggerTestImpl.logMessages.stream().anyMatch(msg ->
+ msg.getType() == LogMessageType.NETWORK_REQUEST &&
+ msg.getLocation().contains("publish")
+ )
+ );
+
+ assertTrue(
+ "Should have called publish API. LogMessage type should be NETWORK_RESPONSE",
+ CustomLoggerTestImpl.logMessages.stream().anyMatch(msg ->
+ msg.getType() == LogMessageType.NETWORK_RESPONSE &&
+ msg.getLocation().contains("publish")
+ )
+ );
+
+ pubNub.destroy();
+ }
+
+}
diff --git a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/MessageActionsTest.java b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/MessageActionsTest.java
index e5d4e94229..a46e215643 100644
--- a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/MessageActionsTest.java
+++ b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/MessageActionsTest.java
@@ -231,7 +231,7 @@ public void onMore(List actions) {
@Override
public void onDone() {
- log.error(String.format("onDone %s", count.get()));
+ System.out.println(String.format("onDone %s", count.get()));
success.set(count.get() == messageCount);
}
});
diff --git a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/PNConfigurationIntegrationTests.java b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/PNConfigurationIntegrationTests.java
index 3aaad6687b..dd1135e9da 100644
--- a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/PNConfigurationIntegrationTests.java
+++ b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/PNConfigurationIntegrationTests.java
@@ -2,6 +2,7 @@
import com.pubnub.api.PubNubException;
import com.pubnub.api.UserId;
+import com.pubnub.api.integration.util.CustomLoggerTestImpl;
import com.pubnub.api.integration.util.ITTestConfig;
import com.pubnub.api.integration.util.Utils;
import com.pubnub.api.java.PubNub;
@@ -11,6 +12,8 @@
import org.junit.Assert;
import org.junit.Test;
+import java.util.Arrays;
+
public class PNConfigurationIntegrationTests {
final ITTestConfig itTestConfig = ConfigFactory.create(ITTestConfig.class, System.getenv());
@@ -35,12 +38,14 @@ public void createConfigurationWithConfigurationActionBlock() throws PubNubExcep
String expectedUuid = PubNub.generateUUID();
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId(expectedUuid), itTestConfig.subscribeKey())
- .publishKey(itTestConfig.publishKey());
+ .publishKey(itTestConfig.publishKey())
+ .customLoggers( Arrays.asList(new CustomLoggerTestImpl()));
PubNub pubNub = PubNub.create(configBuilder.build());
Assert.assertEquals(expectedUuid, pubNub.getConfiguration().getUserId().getValue());
Assert.assertEquals(itTestConfig.subscribeKey(), pubNub.getConfiguration().getSubscribeKey());
Assert.assertEquals(itTestConfig.publishKey(), pubNub.getConfiguration().getPublishKey());
+ Assert.assertTrue(pubNub.getConfiguration().getCustomLoggers().get(0) instanceof CustomLoggerTestImpl);
}
@Test
diff --git a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/channel/ChannelMetadataIT.java b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/channel/ChannelMetadataIT.java
index 16ff51e263..2276a30fc9 100644
--- a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/channel/ChannelMetadataIT.java
+++ b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/channel/ChannelMetadataIT.java
@@ -12,8 +12,6 @@
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
@@ -35,7 +33,6 @@
import static org.junit.Assert.assertNotNull;
public class ChannelMetadataIT extends ObjectsApiBaseIT {
- private static final Logger LOG = LoggerFactory.getLogger(ChannelMetadataIT.class);
private static final int NUMBER_OF_RANDOM_TEST_NAMES = 10;
private static final int FETCH_LIMIT = 3;
@@ -272,7 +269,7 @@ public void cleanUp() {
.channel(setChannelMetadataResult.getData().getId())
.sync();
} catch (Exception e) {
- LOG.warn("Could not cleanup {}", setChannelMetadataResult, e);
+ System.out.printf("Could not cleanup {}", setChannelMetadataResult);
}
});
}
diff --git a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/members/ChannelMembersIT.java b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/members/ChannelMembersIT.java
index 677d602f48..e4450a44ae 100644
--- a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/members/ChannelMembersIT.java
+++ b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/members/ChannelMembersIT.java
@@ -17,8 +17,6 @@
import org.jetbrains.annotations.Nullable;
import org.junit.After;
import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
@@ -48,7 +46,6 @@
import static org.junit.Assert.assertTrue;
public class ChannelMembersIT extends ObjectsApiBaseIT {
- private static final Logger LOG = LoggerFactory.getLogger(ChannelMembersIT.class);
private static final String STATUS_01 = "myStatus01";
private static final String TYPE_01 = "myType01" + random();
private static final String TYPE_02 = "myType02" + random();
@@ -475,7 +472,7 @@ public void cleanUp() {
.sync();
} catch (Exception e) {
- LOG.warn("Could not cleanup {}", createdMembers, e);
+ System.out.printf("Could not cleanup %s%n", createdMembers);
}
}
}
diff --git a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/memberships/MembershipIT.java b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/memberships/MembershipIT.java
index 2b17726406..c61d650bc0 100644
--- a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/memberships/MembershipIT.java
+++ b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/memberships/MembershipIT.java
@@ -14,8 +14,6 @@
import org.apache.http.HttpStatus;
import org.junit.After;
import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
@@ -40,7 +38,6 @@
import static org.junit.Assert.assertNull;
public class MembershipIT extends ObjectsApiBaseIT {
- private static final Logger LOG = LoggerFactory.getLogger(MembershipIT.class);
private static final String STATUS = "status";
private static final String CHANNEL = "channel";
@@ -453,7 +450,7 @@ public void cleanUp() {
pubNubUnderTest.removeMemberships(channelIds).sync();
} catch (Exception e) {
- LOG.warn("Could not cleanup {}", createdMembership, e);
+ System.out.printf("Could not cleanup {}", createdMembership);
}
}
}
diff --git a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/uuid/UUIDMetadataIT.java b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/uuid/UUIDMetadataIT.java
index 556aff093b..7a8fe3ab3f 100644
--- a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/uuid/UUIDMetadataIT.java
+++ b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/objects/uuid/UUIDMetadataIT.java
@@ -10,8 +10,6 @@
import org.apache.http.HttpStatus;
import org.junit.After;
import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
@@ -33,7 +31,6 @@
import static org.junit.Assert.assertNotNull;
public class UUIDMetadataIT extends ObjectsApiBaseIT {
- private static final Logger LOG = LoggerFactory.getLogger(UUIDMetadataIT.class);
private static final int NUMBER_OF_RANDOM_TEST_UUIDS = 10;
private static final int FETCH_LIMIT = 3;
@@ -184,7 +181,7 @@ public void cleanUp() {
.uuid(pnSetUUIDMetadataResult.getData().getId())
.sync();
} catch (Exception e) {
- LOG.warn("Could not cleanup {}", pnSetUUIDMetadataResult, e);
+ System.out.printf("Could not cleanup {}", pnSetUUIDMetadataResult, e);
}
});
}
diff --git a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/pam/AccessManagerIntegrationTest.java b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/pam/AccessManagerIntegrationTest.java
index 929f7ea3b9..350a99bb11 100644
--- a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/pam/AccessManagerIntegrationTest.java
+++ b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/pam/AccessManagerIntegrationTest.java
@@ -56,7 +56,7 @@ abstract class AccessManagerIntegrationTest extends BaseIntegrationTest {
@Override
protected void onPrePubNub() {
- log.warn("onPrePubNub");
+ System.out.println("onPrePubNub");
expectedChannel = randomChannel();
authKey = "auth_".concat(random());
authKey = authKey.toLowerCase();
@@ -71,7 +71,7 @@ protected void onBefore() {
if (performOnServer()) {
pubNub = server;
}
- log.warn("performOnServer: " + performOnServer());
+ System.out.println("performOnServer: " + performOnServer());
if (addDelays) {
pause(3);
@@ -970,9 +970,9 @@ private void requestAccess(Integer... bitmasks) {
}
if (!revokeAllAccess) {
- log.info(String.format("Requesting access for %1$s at %2$s level", sum, getPamLevel()));
+ System.out.println(String.format("Requesting access for %1$s at %2$s level", sum, getPamLevel()));
} else {
- log.info("Revoking all access!");
+ System.out.println("Revoking all access!");
}
final List bitList = Arrays.asList(bitmasks);
@@ -1002,7 +1002,7 @@ private void requestAccess(Integer... bitmasks) {
try {
final PNAccessManagerGrantResult grantResult = grantOperationBuilder.sync();
assertNotNull(grantResult);
- log.info(String.format("Access request result: %s", new Gson().toJson(grantResult)));
+ System.out.println(String.format("Access request result: %s", new Gson().toJson(grantResult)));
if (revokeAllAccess) {
assertEquals(LEVEL_APP, grantResult.getLevel());
} else {
diff --git a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/util/BaseIntegrationTest.java b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/util/BaseIntegrationTest.java
index 94e1808739..e30393c5b3 100644
--- a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/util/BaseIntegrationTest.java
+++ b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/util/BaseIntegrationTest.java
@@ -43,8 +43,6 @@
public abstract class BaseIntegrationTest {
- protected Logger log = LoggerFactory.getLogger(BaseIntegrationTest.class);
-
private static String SUB_KEY;
private static String PUB_KEY;
private static String PAM_SUB_KEY;
@@ -149,7 +147,6 @@ private PNConfiguration getBasicPnConfiguration(@Nullable Consumer stringMessages = new ArrayList<>();
+ public static final List logMessages = new ArrayList<>();
+
+ @Override
+ public String getName() {
+ return "CustomLoggerTestImpl";
+ }
+
+ @Override
+ public void info(String message) {
+ if (message != null) {
+ stringMessages.add(message);
+ }
+ }
+
+ @Override
+ public void info(LogMessage logMessage) {
+ logMessages.add(logMessage);
+ }
+
+ @Override
+ public void debug(String message) {
+ if (message != null) {
+ stringMessages.add(message);
+ }
+ }
+
+ @Override
+ public void debug(LogMessage logMessage) {
+ logMessages.add(logMessage);
+ }
+
+ public static void clear() {
+ stringMessages.clear();
+ logMessages.clear();
+ }
+}
diff --git a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/PubNubForJavaImpl.kt b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/PubNubForJavaImpl.kt
index db298dbb0c..9d94e60332 100644
--- a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/PubNubForJavaImpl.kt
+++ b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/PubNubForJavaImpl.kt
@@ -67,6 +67,8 @@ import com.pubnub.api.java.v2.callbacks.EventListener
import com.pubnub.api.java.v2.callbacks.StatusListener
import com.pubnub.api.java.v2.endpoints.pubsub.PublishBuilder
import com.pubnub.api.java.v2.endpoints.pubsub.SignalBuilder
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.java.builder.PresenceBuilderImpl
import com.pubnub.internal.java.builder.SubscribeBuilderImpl
@@ -176,6 +178,15 @@ open class PubNubForJavaImpl(configuration: PNConfiguration) :
}
override fun history(): History {
+ logger.warn(
+ LogMessage(
+ message = LogMessageContent.Text(
+ "DEPRECATED: history() is deprecated. Use fetchMessages() instead."
+ ),
+ details = "This method will be removed in a future version",
+ location = this::class.java.simpleName
+ )
+ )
return HistoryImpl(this)
}
@@ -197,6 +208,15 @@ open class PubNubForJavaImpl(configuration: PNConfiguration) :
@Deprecated("Use {@link #grantToken(int)} instead.")
override fun grantToken(): GrantTokenBuilder {
+ logger.warn(
+ LogMessage(
+ message = LogMessageContent.Text(
+ "DEPRECATED: grantToken() without TTL is deprecated. Use grantToken(int ttl) instead."
+ ),
+ details = "This method will be removed in a future version",
+ location = this::class.java.simpleName
+ )
+ )
return GrantTokenImpl(this)
}
@@ -217,6 +237,15 @@ open class PubNubForJavaImpl(configuration: PNConfiguration) :
}
override fun publish(): Publish {
+ logger.warn(
+ LogMessage(
+ message = LogMessageContent.Text(
+ "DEPRECATED: publish() builder pattern is deprecated. Use publish(Object message, String channel) instead."
+ ),
+ details = "This method will be removed in a future version",
+ location = this::class.java.simpleName
+ )
+ )
return PublishImpl(this)
}
@@ -225,6 +254,15 @@ open class PubNubForJavaImpl(configuration: PNConfiguration) :
}
override fun signal(): Signal {
+ logger.warn(
+ LogMessage(
+ message = LogMessageContent.Text(
+ "DEPRECATED: signal() builder pattern is deprecated. Use signal(Object message, String channel) instead."
+ ),
+ details = "This method will be removed in a future version",
+ location = this::class.java.simpleName
+ )
+ )
return SignalImpl(this)
}
@@ -420,6 +458,15 @@ open class PubNubForJavaImpl(configuration: PNConfiguration) :
}
override fun fire(): Publish {
+ logger.warn(
+ LogMessage(
+ message = LogMessageContent.Text(
+ "DEPRECATED: fire() builder pattern is deprecated. Use fire(Object message, String channel) instead."
+ ),
+ details = "This method will be removed in a future version",
+ location = this::class.java.simpleName
+ )
+ )
return publish().shouldStore(false).replicate(false)
}
diff --git a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/PNConfigurationImpl.kt b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/PNConfigurationImpl.kt
index c75f9bf0ca..b92b477edf 100644
--- a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/PNConfigurationImpl.kt
+++ b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/PNConfigurationImpl.kt
@@ -6,13 +6,15 @@ import com.pubnub.api.enums.PNHeartbeatNotificationOptions
import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.java.v2.PNConfiguration
import com.pubnub.api.java.v2.PNConfigurationOverride
+import com.pubnub.api.logging.CustomLogger
+import com.pubnub.api.logging.LogConfig
import com.pubnub.api.retry.RetryConfiguration
import com.pubnub.api.retry.RetryableEndpointGroup
+import com.pubnub.internal.crypto.CryptoModuleImpl
import okhttp3.Authenticator
import okhttp3.CertificatePinner
import okhttp3.ConnectionSpec
import okhttp3.logging.HttpLoggingInterceptor
-import org.slf4j.LoggerFactory
import java.net.Proxy
import java.net.ProxySelector
import javax.net.ssl.HostnameVerifier
@@ -71,6 +73,7 @@ class PNConfigurationImpl(
)
),
override val managePresenceListManually: Boolean = false,
+ override val customLoggers: List? = null,
) : PNConfiguration {
companion object {
const val DEFAULT_DEDUPE_SIZE = 100
@@ -81,12 +84,26 @@ class PNConfigurationImpl(
const val CONNECT_TIMEOUT = 5
}
+ // this method is used from cryptoModuleWithLogConfig using reflection
+ fun getCryptoModuleWithLogConfig(logConfig: LogConfig): CryptoModule? {
+ return cryptoModule?.let { module ->
+ if (module is CryptoModuleImpl) {
+ CryptoModuleImpl(
+ primaryCryptor = module.primaryCryptor,
+ cryptorsForDecryptionOnly = module.cryptorsForDecryptionOnly,
+ logConfig = logConfig
+ )
+ } else {
+ // For custom implementations, return the original instance
+ module
+ }
+ }
+ }
+
class Builder internal constructor(defaultConfiguration: com.pubnub.api.v2.PNConfiguration) :
PNConfiguration.Builder, PNConfigurationOverride.Builder {
constructor(userId: UserId, subscribeKey: String) : this(PNConfigurationImpl(userId, subscribeKey))
- private val log = LoggerFactory.getLogger(this::class.simpleName)
-
override var userId: UserId = defaultConfiguration.userId
override fun setUserId(userId: UserId): PNConfiguration.Builder {
@@ -143,6 +160,15 @@ class PNConfigurationImpl(
override var secure: Boolean = defaultConfiguration.secure
+ @Deprecated(
+ message = "LogVerbosity setting is deprecated and will be removed in future versions. " +
+ "For logging configuration:\n" +
+ "1. Use an SLF4J implementation (recommended)\n" +
+ "2. Or implement CustomLogger interface and set via customLoggers property. " +
+ "Use CustomLogger if your slf4j implementation like logback, log4j2, etc. can't meet " +
+ "your specific logging requirements.",
+ level = DeprecationLevel.WARNING
+ )
override fun logVerbosity(logVerbosity: PNLogVerbosity): Builder {
this.logVerbosity = logVerbosity
return this
@@ -160,7 +186,7 @@ class PNConfigurationImpl(
override fun presenceTimeout(presenceTimeout: Int): Builder {
this.presenceTimeout = if (presenceTimeout < MINIMUM_PRESENCE_TIMEOUT) {
- log.warn("Presence timeout is too low. Defaulting to: $MINIMUM_PRESENCE_TIMEOUT")
+ println("Presence timeout is too low. Defaulting to: $MINIMUM_PRESENCE_TIMEOUT")
MINIMUM_PRESENCE_TIMEOUT
} else {
presenceTimeout
@@ -291,6 +317,10 @@ class PNConfigurationImpl(
override var certificatePinner: CertificatePinner? = defaultConfiguration.certificatePinner
+ @Deprecated(
+ message = "This setting is deprecated. Use customLoggers instead.",
+ level = DeprecationLevel.WARNING
+ )
override fun httpLoggingInterceptor(httpLoggingInterceptor: HttpLoggingInterceptor?): Builder {
this.httpLoggingInterceptor = httpLoggingInterceptor
return this
@@ -368,6 +398,13 @@ class PNConfigurationImpl(
override var managePresenceListManually: Boolean = defaultConfiguration.managePresenceListManually
+ override fun customLoggers(customLoggers: List?): Builder {
+ this.customLoggers = customLoggers
+ return this
+ }
+
+ override var customLoggers: List? = defaultConfiguration.customLoggers
+
override fun build(): PNConfiguration {
return PNConfigurationImpl(
userId = userId,
@@ -408,6 +445,7 @@ class PNConfigurationImpl(
pnsdkSuffixes = pnsdkSuffixes,
retryConfiguration = retryConfiguration,
managePresenceListManually = managePresenceListManually,
+ customLoggers = customLoggers
)
}
}
diff --git a/pubnub-gson/pubnub-gson-impl/src/test/kotlin/com/pubnub/internal/java/v2/subscription/SubscriptionSetImplTest.kt b/pubnub-gson/pubnub-gson-impl/src/test/kotlin/com/pubnub/internal/java/v2/subscription/SubscriptionSetImplTest.kt
index 7a556b06fe..1bad279f06 100644
--- a/pubnub-gson/pubnub-gson-impl/src/test/kotlin/com/pubnub/internal/java/v2/subscription/SubscriptionSetImplTest.kt
+++ b/pubnub-gson/pubnub-gson-impl/src/test/kotlin/com/pubnub/internal/java/v2/subscription/SubscriptionSetImplTest.kt
@@ -1,5 +1,6 @@
package com.pubnub.internal.java.v2.subscription
+import com.pubnub.api.logging.LogConfig
import com.pubnub.api.v2.subscriptions.EmptyOptions
import com.pubnub.api.v2.subscriptions.SubscriptionOptions
import com.pubnub.internal.java.PubNubForJavaImpl
@@ -23,6 +24,8 @@ class SubscriptionSetImplTest {
@BeforeEach
fun setUp() {
+ val testLogConfig = LogConfig("test-instance-id", "test-user-id")
+ every { pubNubImpl.logConfig } returns testLogConfig
val listenerManager = ListenerManager(pubNubImpl)
every { pubNubImpl.listenerManager } returns listenerManager
diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/retry/RetryConfiguration.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/retry/RetryConfiguration.kt
index 0e4ee28504..174bcf3356 100644
--- a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/retry/RetryConfiguration.kt
+++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/retry/RetryConfiguration.kt
@@ -1,7 +1,6 @@
package com.pubnub.api.retry
// import org.jetbrains.annotations.TestOnly TODO
-// import org.slf4j.LoggerFactory TODO
import kotlin.jvm.JvmSynthetic
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
@@ -32,8 +31,6 @@ sealed class RetryConfiguration {
val excludedOperations: List = emptyList(),
isInternal: Boolean = false,
) : RetryConfiguration() {
-// private val log = LoggerFactory.getLogger(this.javaClass.simpleName + "-" + "RetryConfiguration")
-
constructor(
delayInSec: Int = MIN_DELAY,
maxRetryNumber: Int = MAX_RETRIES,
@@ -48,11 +45,9 @@ sealed class RetryConfiguration {
init {
if (!isInternal) {
if (delayInSec < MIN_DELAY.seconds) {
-// log.trace("Provided delay is less than $MIN_DELAY, setting it to $MIN_DELAY")
delayInSec = MIN_DELAY.seconds
}
if (maxRetryNumber > MAX_RETRIES) {
-// log.trace("Provided maxRetryNumber is greater than $MAX_RETRIES, setting it to $MAX_RETRIES")
maxRetryNumber = MAX_RETRIES
}
}
@@ -89,8 +84,6 @@ sealed class RetryConfiguration {
val excludedOperations: List = emptyList(),
isInternal: Boolean = false,
) : RetryConfiguration() {
-// private val log = LoggerFactory.getLogger(this.javaClass.simpleName + "-" + "RetryConfiguration")
-
constructor(
minDelayInSec: Int = MIN_DELAY,
maxDelayInSec: Int = MAX_DELAY,
@@ -125,7 +118,7 @@ sealed class RetryConfiguration {
maxRetryNumber = maxRetryNumber.coerceAtMost(MAX_RETRIES)
if (minDelayInSec != originalMinDelayInSec || maxDelayInSec != originalMaxDelayInSec || maxRetryNumber != originalMaxRetryNumber) {
-// log.trace("Adjusted values: minDelayInSec=$minDelayInSec, maxDelayInSec=$maxDelayInSec, maxRetryNumber=$maxRetryNumber")
+ // no action
}
}
}
diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/crypto/CryptoModule.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/crypto/CryptoModule.kt
index 6fe8a26ffc..6106fae9db 100644
--- a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/crypto/CryptoModule.kt
+++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/crypto/CryptoModule.kt
@@ -1,6 +1,7 @@
package com.pubnub.api.crypto
import com.pubnub.api.crypto.cryptor.Cryptor
+import com.pubnub.api.logging.LogConfig
import java.io.InputStream
interface CryptoModule {
@@ -16,7 +17,10 @@ interface CryptoModule {
): CryptoModule {
return instantiateCryptoModuleImpl(
primaryCryptor = instantiateLegacyCryptor(cipherKey, randomIv),
- cryptorsForDecryptionOnly = listOf(instantiateLegacyCryptor(cipherKey, randomIv), instantiateAesCbcCryptor(cipherKey)),
+ cryptorsForDecryptionOnly = listOf(
+ instantiateLegacyCryptor(cipherKey, randomIv),
+ instantiateAesCbcCryptor(cipherKey)
+ ),
)
}
@@ -27,7 +31,10 @@ interface CryptoModule {
): CryptoModule {
return instantiateCryptoModuleImpl(
primaryCryptor = instantiateAesCbcCryptor(cipherKey),
- cryptorsForDecryptionOnly = listOf(instantiateAesCbcCryptor(cipherKey), instantiateLegacyCryptor(cipherKey, randomIv)),
+ cryptorsForDecryptionOnly = listOf(
+ instantiateAesCbcCryptor(cipherKey),
+ instantiateLegacyCryptor(cipherKey, randomIv)
+ ),
)
}
@@ -52,10 +59,13 @@ private fun instantiateCryptoModuleImpl(
primaryCryptor: Cryptor,
cryptorsForDecryptionOnly: List,
): CryptoModule {
- return Class.forName("com.pubnub.internal.crypto.CryptoModuleImpl").getConstructor(Cryptor::class.java, List::class.java).newInstance(
- primaryCryptor,
- cryptorsForDecryptionOnly,
- ) as CryptoModule
+ return Class.forName("com.pubnub.internal.crypto.CryptoModuleImpl")
+ .getConstructor(Cryptor::class.java, List::class.java, LogConfig::class.java)
+ .newInstance(
+ primaryCryptor,
+ cryptorsForDecryptionOnly,
+ null
+ ) as CryptoModule
}
private fun instantiateLegacyCryptor(
@@ -71,7 +81,8 @@ private fun instantiateLegacyCryptor(
}
private fun instantiateAesCbcCryptor(cipherKey: String): Cryptor {
- return Class.forName("com.pubnub.internal.crypto.cryptor.AesCbcCryptor").getConstructor(String::class.java).newInstance(
- cipherKey,
- ) as Cryptor
+ return Class.forName("com.pubnub.internal.crypto.cryptor.AesCbcCryptor").getConstructor(String::class.java)
+ .newInstance(
+ cipherKey,
+ ) as Cryptor
}
diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/CustomLogger.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/CustomLogger.kt
new file mode 100644
index 0000000000..55b065ad05
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/CustomLogger.kt
@@ -0,0 +1,82 @@
+package com.pubnub.api.logging
+
+/**
+ * Interface for custom logger implementations.
+ * Provides both string-based and structured LogMessage-based logging.
+ */
+interface CustomLogger {
+ /**
+ * The name of this logger implementation.
+ */
+ val name: String get() = "CustomLogger"
+
+ /**
+ * Log a trace message with a string.
+ */
+ fun trace(message: String?) {
+ // Default implementation does nothing
+ }
+
+ /**
+ * Log a trace message with structured data.
+ */
+ fun trace(logMessage: LogMessage) {
+ // Default implementation does nothing
+ }
+
+ /**
+ * Log a debug message with a string.
+ */
+ fun debug(message: String?) {
+ // Default implementation does nothing
+ }
+
+ /**
+ * Log a debug message with structured data.
+ */
+ fun debug(logMessage: LogMessage) {
+ // Default implementation does nothing
+ }
+
+ /**
+ * Log an info message with a string.
+ */
+ fun info(message: String?) {
+ // Default implementation does nothing
+ }
+
+ /**
+ * Log an info message with structured data.
+ */
+ fun info(logMessage: LogMessage) {
+ // Default implementation does nothing
+ }
+
+ /**
+ * Log a warning message with a string.
+ */
+ fun warn(message: String?) {
+ // Default implementation does nothing
+ }
+
+ /**
+ * Log a warning message with structured data.
+ */
+ fun warn(logMessage: LogMessage) {
+ // Default implementation does nothing
+ }
+
+ /**
+ * Log an error message with a string.
+ */
+ fun error(message: String?) {
+ // Default implementation does nothing
+ }
+
+ /**
+ * Log an error message with structured data.
+ */
+ fun error(logMessage: LogMessage) {
+ // Default implementation does nothing
+ }
+}
diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/LogConfig.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/LogConfig.kt
new file mode 100644
index 0000000000..c93784b656
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/LogConfig.kt
@@ -0,0 +1,10 @@
+package com.pubnub.api.logging
+
+/**
+ * Configuration for logging system with validation.
+ *
+ * @param pnInstanceId The PubNub instance identifier - must not be blank
+ * @param userId The user identifier - must not be blank
+ * @param customLoggers Optional list of custom loggers to use
+ */
+class LogConfig(val pnInstanceId: String, val userId: String, val customLoggers: List? = null)
diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/LogMessage.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/LogMessage.kt
new file mode 100644
index 0000000000..6a147b82a7
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/LogMessage.kt
@@ -0,0 +1,42 @@
+package com.pubnub.api.logging
+
+import com.google.gson.annotations.SerializedName
+import org.slf4j.event.Level
+import java.time.LocalTime
+import java.time.format.DateTimeFormatter
+
+/**
+ * Represents a structured log message with validation and sanitization.
+ *
+ * @param pubNubId The PubNub instance identifier
+ * @param logLevel The logging level
+ * @param location The source location of the log
+ * @param type The type of log message (automatically inferred from message content)
+ * @param message The log message content
+ * @param details Optional additional details (will be sanitized)
+ * @param timestamp The timestamp when the log was created
+ */
+class LogMessage(
+ @SerializedName("message")
+ val message: LogMessageContent,
+ @SerializedName("details")
+ val details: String? = null,
+ @SerializedName("type")
+ val type: LogMessageType = message.inferType(),
+ @SerializedName("location")
+ val location: String? = null, // this value will be set in CompositeLogger if not set
+ @SerializedName("pubNubId")
+ val pubNubId: String? = null, // this value will be set in CompositeLogger
+ @SerializedName("logLevel")
+ val logLevel: Level? = null, // this value will be set in CompositeLogger
+ @SerializedName("timestamp")
+ val timestamp: String = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss.SSS")),
+)
+
+private fun LogMessageContent.inferType(): LogMessageType = when (this) {
+ is LogMessageContent.Text -> LogMessageType.TEXT
+ is LogMessageContent.Object -> LogMessageType.OBJECT
+ is LogMessageContent.Error -> LogMessageType.ERROR
+ is LogMessageContent.NetworkRequest -> LogMessageType.NETWORK_REQUEST
+ is LogMessageContent.NetworkResponse -> LogMessageType.NETWORK_RESPONSE
+}
diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/LogMessageContent.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/LogMessageContent.kt
new file mode 100644
index 0000000000..d3447ee442
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/LogMessageContent.kt
@@ -0,0 +1,58 @@
+package com.pubnub.api.logging
+
+import com.google.gson.annotations.SerializedName
+
+/**
+ * Sealed class representing different types of log message content.
+ * This provides type safety when working with different message types.
+ */
+sealed class LogMessageContent {
+ /**
+ * Plain string message for text type logs.
+ */
+ data class Text(
+ @SerializedName("message")
+ val message: String
+ ) : LogMessageContent()
+
+ /**
+ * Dictionary/object message for object type logs.
+ */
+ data class Object(
+ @SerializedName("message")
+ val message: Map
+ ) : LogMessageContent()
+
+ /**
+ * Error message with type, message, and stack trace.
+ */
+ data class Error(
+ @SerializedName("message")
+ val message: ErrorDetails
+ ) : LogMessageContent()
+
+ /**
+ * Network request message.
+ */
+ data class NetworkRequest(
+ @SerializedName("message")
+ val message: NetworkLog.Request
+ ) : LogMessageContent()
+
+ /**
+ * Network response message.
+ */
+ data class NetworkResponse(
+ @SerializedName("message")
+ val message: NetworkLog.Response
+ ) : LogMessageContent()
+}
+
+data class ErrorDetails(
+ @SerializedName("type")
+ val type: String? = null,
+ @SerializedName("message")
+ val message: String,
+ @SerializedName("stack")
+ val stack: List? = null
+)
diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/LogMessageType.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/LogMessageType.kt
new file mode 100644
index 0000000000..c5a5ad5d04
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/LogMessageType.kt
@@ -0,0 +1,9 @@
+package com.pubnub.api.logging
+
+enum class LogMessageType(val type: String) {
+ TEXT("text"),
+ OBJECT("object"),
+ ERROR("error"),
+ NETWORK_REQUEST("network-request"),
+ NETWORK_RESPONSE("network-response")
+}
diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/NetworkLog.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/NetworkLog.kt
new file mode 100644
index 0000000000..18650efcd4
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/NetworkLog.kt
@@ -0,0 +1,19 @@
+package com.pubnub.api.logging
+
+import com.google.gson.annotations.SerializedName
+
+sealed class NetworkLog {
+ data class Request(
+ @SerializedName("message")
+ val message: NetworkRequestMessage,
+ @SerializedName("canceled")
+ val canceled: Boolean = false,
+ @SerializedName("failed")
+ val failed: Boolean = false
+ ) : NetworkLog()
+
+ data class Response(
+ @SerializedName("message")
+ val message: NetworkResponseMessage
+ ) : NetworkLog()
+}
diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/NetworkRequestMessage.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/NetworkRequestMessage.kt
new file mode 100644
index 0000000000..99069d633c
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/NetworkRequestMessage.kt
@@ -0,0 +1,43 @@
+package com.pubnub.api.logging
+
+import com.google.gson.annotations.SerializedName
+
+data class NetworkRequestMessage(
+ @SerializedName("origin")
+ val origin: String,
+ @SerializedName("path")
+ val path: String,
+ @SerializedName("query")
+ val query: Map? = null,
+ @SerializedName("method")
+ val method: HttpMethod,
+ @SerializedName("headers")
+ val headers: Map? = null,
+ @SerializedName("formData")
+ val formData: Map? = null,
+ @SerializedName("body")
+ val body: String? = null,
+ @SerializedName("timeout")
+ val timeout: Long? = null,
+ @SerializedName("identifier")
+ val identifier: String? = null
+)
+
+enum class HttpMethod(val value: String) {
+ GET("get"),
+ POST("post"),
+ PATCH("patch"),
+ DELETE("delete");
+
+ companion object {
+ fun fromString(method: String): HttpMethod {
+ return when (method.lowercase()) {
+ "get" -> GET
+ "post" -> POST
+ "patch" -> PATCH
+ "delete" -> DELETE
+ else -> throw IllegalStateException("Unknown HTTP method: $method")
+ }
+ }
+ }
+}
diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/NetworkResponseMessage.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/NetworkResponseMessage.kt
new file mode 100644
index 0000000000..a75f426752
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/NetworkResponseMessage.kt
@@ -0,0 +1,14 @@
+package com.pubnub.api.logging
+
+import com.google.gson.annotations.SerializedName
+
+data class NetworkResponseMessage(
+ @SerializedName("url")
+ val url: String,
+ @SerializedName("status")
+ val status: Int,
+ @SerializedName("headers")
+ val headers: Map? = null,
+ @SerializedName("body")
+ val body: String? = null
+)
diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt
index af2d5c353a..1afd8174f5 100644
--- a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt
+++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt
@@ -4,6 +4,7 @@ import com.pubnub.api.UserId
import com.pubnub.api.crypto.CryptoModule
import com.pubnub.api.enums.PNHeartbeatNotificationOptions
import com.pubnub.api.enums.PNLogVerbosity
+import com.pubnub.api.logging.CustomLogger
import com.pubnub.api.retry.RetryConfiguration
import okhttp3.Authenticator
import okhttp3.CertificatePinner
@@ -77,6 +78,13 @@ actual interface PNConfiguration {
/**
* Set to [PNLogVerbosity.BODY] to enable logging of network traffic, otherwise se to [PNLogVerbosity.NONE].
*/
+ @Deprecated(
+ message = "LogVerbosity setting is deprecated and will be removed in future versions. " +
+ "For logging configuration:\n" +
+ "1. Use an SLF4J implementation (recommended)\n" +
+ "2. Or implement CustomLogger interface and set via customLoggers property",
+ level = DeprecationLevel.WARNING
+ )
actual val logVerbosity: PNLogVerbosity
/**
@@ -124,7 +132,7 @@ actual interface PNConfiguration {
* For non subscribe operations (publish, herenow, etc),
* This property relates to a read timeout that is applied from the moment the connection between a client
* and the server has been successfully established. It defines a maximum time of inactivity between two
- * data packets when waiting for the server’s response.
+ * data packets when waiting for the server's response.
*
* The value is in seconds.
*
@@ -141,7 +149,7 @@ actual interface PNConfiguration {
* For non subscribe operations (publish, herenow, etc),
* This property relates to a read timeout that is applied from the moment the connection between a client
* and the server has been successfully established. It defines a maximum time of inactivity between two
- * data packets when waiting for the server’s response.
+ * data packets when waiting for the server's response.
*
* The value is in seconds.
*
@@ -234,6 +242,10 @@ actual interface PNConfiguration {
*
* @see [HttpLoggingInterceptor]
*/
+ @Deprecated(
+ message = "This setting is deprecated. Use customLoggers instead.",
+ level = DeprecationLevel.WARNING
+ )
val httpLoggingInterceptor: HttpLoggingInterceptor?
/**
@@ -287,6 +299,12 @@ actual interface PNConfiguration {
*/
val managePresenceListManually: Boolean
+ /**
+ * Custom loggers list for creating additional logger instances.
+ * Use it if your slf4j implementation like logback, log4j2, etc. can't meet your specific logging requirements.
+ */
+ val customLoggers: List?
+
@Deprecated(
level = DeprecationLevel.WARNING,
message = """Use UserId instead e.g. config.userId.value""",
@@ -381,6 +399,15 @@ actual interface PNConfiguration {
/**
* Set to [PNLogVerbosity.BODY] to enable logging of network traffic, otherwise se to [PNLogVerbosity.NONE].
*/
+ @Deprecated(
+ message = "LogVerbosity setting is deprecated and will be removed in future versions. " +
+ "For logging configuration:\n" +
+ "1. Use an SLF4J implementation (recommended)\n" +
+ "2. Or implement CustomLogger interface and set via customLoggers property. " +
+ "Use CustomLogger if your slf4j implementation like logback, log4j2, etc. can't meet " +
+ "your specific logging requirements.",
+ level = DeprecationLevel.WARNING
+ )
var logVerbosity: PNLogVerbosity
/**
@@ -428,7 +455,7 @@ actual interface PNConfiguration {
* For non subscribe operations (publish, herenow, etc),
* This property relates to a read timeout that is applied from the moment the connection between a client
* and the server has been successfully established. It defines a maximum time of inactivity between two
- * data packets when waiting for the server’s response.
+ * data packets when waiting for the server's response.
*
* The value is in seconds.
*
@@ -448,7 +475,7 @@ actual interface PNConfiguration {
* For non subscribe operations (publish, herenow, etc),
* This property relates to a read timeout that is applied from the moment the connection between a client
* and the server has been successfully established. It defines a maximum time of inactivity between two
- * data packets when waiting for the server’s response.
+ * data packets when waiting for the server's response.
*
* The value is in seconds.
*
@@ -541,6 +568,10 @@ actual interface PNConfiguration {
*
* @see [HttpLoggingInterceptor]
*/
+ @Deprecated(
+ message = "This setting is deprecated. Use customLoggers instead",
+ level = DeprecationLevel.WARNING
+ )
var httpLoggingInterceptor: HttpLoggingInterceptor?
/**
@@ -578,7 +609,7 @@ actual interface PNConfiguration {
* Retry configuration for requests.
* Defaults to [RetryConfiguration.Exponential] enabled only for subscription endpoint (other endpoints are excluded).
*
- * Use [RetryConfiguration.Linear] to set retry with linear delay intervar
+ * Use [RetryConfiguration.Linear] to set retry with linear delay interval
* Use [RetryConfiguration.Exponential] to set retry with exponential delay interval
* Delay will vary from provided value by random value.
*/
@@ -594,6 +625,12 @@ actual interface PNConfiguration {
*/
var managePresenceListManually: Boolean
+ /**
+ * Custom loggers list for creating additional logger instances.
+ * Use it if your slf4j implementation like logback, log4j2, etc. can't meet your specific logging requirements.
+ */
+ var customLoggers: List?
+
/**
* Create a [PNConfiguration] object with values from this builder.
*/
@@ -693,7 +730,7 @@ interface PNConfigurationOverride {
* For non subscribe operations (publish, herenow, etc),
* This property relates to a read timeout that is applied from the moment the connection between a client
* and the server has been successfully established. It defines a maximum time of inactivity between two
- * data packets when waiting for the server’s response.
+ * data packets when waiting for the server's response.
*
* The value is in seconds.
*
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/appContext/GetAllUUIDMetadataMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/appContext/GetAllUUIDMetadataMain.kt
index da2eb8de99..af738669dd 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/appContext/GetAllUUIDMetadataMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/appContext/GetAllUUIDMetadataMain.kt
@@ -5,7 +5,6 @@ package com.pubnub.docs.appContext
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.v2.PNConfiguration
/**
@@ -22,7 +21,6 @@ fun main() {
val userId = UserId("uuid-metadata-demo-user")
val config = PNConfiguration.builder(userId, "demo").apply {
publishKey = "demo"
- logVerbosity = PNLogVerbosity.BODY // Enable debug logging of network calls
}.build()
// 2. Create PubNub instance
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/configuration/ConfigurationMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/configuration/ConfigurationMain.kt
index be9a34ef50..78c81eb75f 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/configuration/ConfigurationMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/configuration/ConfigurationMain.kt
@@ -4,7 +4,6 @@ package com.pubnub.docs.configuration
import com.pubnub.api.UserId
import com.pubnub.api.crypto.CryptoModule
import com.pubnub.api.enums.PNHeartbeatNotificationOptions
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.retry.RetryConfiguration
import com.pubnub.api.v2.PNConfiguration
@@ -69,7 +68,6 @@ fun createAdvancedConfig(): PNConfiguration {
suppressLeaveEvents = false // Whether to send leave events when disconnecting
// Debugging parameters
- logVerbosity = PNLogVerbosity.BODY // Enable debug logging of network calls
// Retry configuration (for reconnection)
retryConfiguration = RetryConfiguration.Linear(
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/ChannelGroupMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/ChannelGroupMain.kt
index a9dd704969..cdd962cfac 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/ChannelGroupMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/ChannelGroupMain.kt
@@ -4,7 +4,6 @@ package com.pubnub.docs.entities
// snippet.channelGroup
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.v2.PNConfiguration
import com.pubnub.api.v2.entities.ChannelGroup
@@ -17,7 +16,6 @@ fun main() {
val config = PNConfiguration.builder(userId, "demo").apply {
publishKey = "demo"
subscribeKey = "demo"
- logVerbosity = PNLogVerbosity.BODY // Enable debug logging of network calls
}.build()
// 2. Create PubNub instance
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/ChannelMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/ChannelMain.kt
index 97be211ce8..afc3f03d08 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/ChannelMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/ChannelMain.kt
@@ -4,7 +4,6 @@ package com.pubnub.docs.entities
// snippet.channelMain
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.v2.PNConfiguration
fun main() {
@@ -16,7 +15,6 @@ fun main() {
val config = PNConfiguration.builder(userId, "demo").apply {
publishKey = "demo"
subscribeKey = "demo"
- logVerbosity = PNLogVerbosity.BODY // Enable debug logging of network calls
}.build()
// 2. Create PubNub instance
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/ChannelMetadataMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/ChannelMetadataMain.kt
index 9ba350334c..9f9792a592 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/ChannelMetadataMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/ChannelMetadataMain.kt
@@ -4,7 +4,6 @@ package com.pubnub.docs.entities
// snippet.channelMetadata
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.v2.PNConfiguration
import com.pubnub.api.v2.entities.ChannelMetadata
@@ -17,7 +16,6 @@ fun main() {
val config = PNConfiguration.builder(userId, "demo").apply {
publishKey = "demo"
subscribeKey = "demo"
- logVerbosity = PNLogVerbosity.BODY // Enable debug logging of network calls
}.build()
// 2. Create PubNub instance
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/UserMetadata.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/UserMetadata.kt
index 18ad960293..ca19f3f774 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/UserMetadata.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/entities/UserMetadata.kt
@@ -4,7 +4,6 @@ package com.pubnub.docs.entities
// snippet.userMetadata
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.v2.PNConfiguration
fun main() {
@@ -16,7 +15,6 @@ fun main() {
val config = PNConfiguration.builder(userId, "demo").apply {
publishKey = "demo"
subscribeKey = "demo"
- logVerbosity = PNLogVerbosity.BODY // Enable debug logging of network calls
}.build()
// 2. Create PubNub instance
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/fileSharing/FileSharingMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/fileSharing/FileSharingMain.kt
index 2de4432e65..263c36732d 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/fileSharing/FileSharingMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/fileSharing/FileSharingMain.kt
@@ -4,7 +4,6 @@ package com.pubnub.docs.fileSharing
// snippet.filesBasicUsage
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.v2.PNConfiguration
import java.io.File
import java.io.FileInputStream
@@ -24,7 +23,6 @@ fun main() {
val userId = UserId("file-upload-demo-user")
val config = PNConfiguration.builder(userId, "demo").apply {
publishKey = "demo"
- logVerbosity = PNLogVerbosity.BODY // Enable debug logging of network calls
}.build()
// 2. Create PubNub instance
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LogginExampleMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LogginExampleMain.kt
index 80a0d2a36d..ee37f3c5cf 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LogginExampleMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LogginExampleMain.kt
@@ -4,31 +4,20 @@ package com.pubnub.docs.logging
// snippet.loggingExampleMain
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.v2.PNConfiguration
fun main() {
println("PubNub Logging Example")
println("======================")
- // Configure PubNub with logging enabled
val userId = UserId("loggingDemoUser")
val pnConfiguration = PNConfiguration.builder(userId, "demo").apply {
// Replace "demo" with your Subscribe Key from the PubNub Admin Portal
publishKey = "demo" // Replace with your Publish Key from the PubNub Admin Portal
-
- // Set log verbosity - configure how much detail to log
- // Options:
- // - PNLogVerbosity.NONE (Turn off logging)
- // - PNLogVerbosity.BODY (Log request and response bodies - most detailed)
- logVerbosity = PNLogVerbosity.BODY
}.build()
- println("Logging configured with level: ${pnConfiguration.logVerbosity}")
-
// Initialize PubNub with the configuration
val pubnub = PubNub.create(pnConfiguration)
- println("PubNub initialized with logging enabled")
// Perform operations to generate logs
demonstrateLogging(pubnub)
@@ -83,6 +72,5 @@ fun demonstrateLogging(pubnub: PubNub) {
}
println("\nLogging demonstration complete")
- println("Check your console for detailed logs based on the configured verbosity level")
}
// snippet.end
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LoggingLog4j2Main.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LoggingLog4j2Main.kt
index 853b38e569..36b565483b 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LoggingLog4j2Main.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LoggingLog4j2Main.kt
@@ -3,7 +3,6 @@ package com.pubnub.docs.logging
import com.pubnub.api.PubNub
import com.pubnub.api.PubNubException
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.v2.PNConfiguration
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
@@ -13,28 +12,17 @@ object LoggingLog4j2 {
@JvmStatic
fun main(args: Array) {
- // Configure PubNub with logging enabled
- logger.info("Initializing PubNub with logging enabled")
-
val config = PNConfiguration.builder(
UserId("log4jDemoUser"),
"demo" // Replace with your Subscribe Key from the PubNub Admin Portal
) {
// Add publish key (only required if publishing)
publishKey = "demo" // Replace with your Publish Key from the PubNub Admin Portal
- // Set log verbosity to BODY to see detailed logs
- logVerbosity = PNLogVerbosity.BODY
- // in log4j2.xml configure specific logger for PubNub network calls e.g.
- //
- //
- //
}
// Initialize PubNub with the configuration
val pubnub = PubNub.create(config.build())
- logger.info("PubNub client initialized with BODY level logging")
-
// Perform some operations to generate logs
try {
// Get time operation
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LoggingLogbackMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LoggingLogbackMain.kt
index c01868cddf..d391dd4260 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LoggingLogbackMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LoggingLogbackMain.kt
@@ -5,7 +5,6 @@ package com.pubnub.docs.logging
import com.pubnub.api.PubNub
import com.pubnub.api.PubNubException
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.v2.PNConfiguration
import org.slf4j.Logger
import org.slf4j.LoggerFactory
@@ -18,7 +17,6 @@ object LoggingLogback {
fun main(args: Array) {
logger.info("Starting PubNub logging example...")
- // Configure PubNub with logging enabled
val config = PNConfiguration.builder(
UserId("loggingDemoUser"),
"demo" // Replace with your Subscribe Key from the PubNub Admin Portal
@@ -26,13 +24,6 @@ object LoggingLogback {
// Add publish key (only required if publishing)
publishKey = "demo" // Replace with your Publish Key from the PubNub Admin Portal
- // Set log verbosity - options are:
- // NONE - Turn off logging
- // BODY - Log request and response bodies
- logVerbosity = PNLogVerbosity.BODY
- // in logback.xml configure specific logger for PubNub network calls e.g.
- //
-
// Other optional configurations
secure = true
}
@@ -40,8 +31,6 @@ object LoggingLogback {
// Initialize PubNub with the configuration
val pubnub = PubNub.create(config.build())
- logger.info("PubNub client initialized with BODY level logging")
-
// Perform some operations to generate logs
try {
// Get time operation will generate logs
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LoggingSlf4jSimpleMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LoggingSlf4jSimpleMain.kt
index 512cfd5ebf..6682c75b5c 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LoggingSlf4jSimpleMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/logging/LoggingSlf4jSimpleMain.kt
@@ -5,7 +5,6 @@ package com.pubnub.docs.logging
import com.pubnub.api.PubNub
import com.pubnub.api.PubNubException
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.v2.PNConfiguration
import org.slf4j.Logger
import org.slf4j.LoggerFactory
@@ -15,24 +14,17 @@ object LoggingSlf4jSimpl {
@JvmStatic
fun main(args: Array) {
- // Configure PubNub with logging enabled
- logger.info("Initializing PubNub with logging enabled")
-
val config = PNConfiguration.builder(
UserId("slf4jSimpleDemoUser"),
"demo" // Replace with your Subscribe Key from the PubNub Admin Portal
) {
// Add publish key (only required if publishing)
publishKey = "demo" // Replace with your Publish Key from the PubNub Admin Portal
- // Set log verbosity to BODY to see detailed logs
- logVerbosity = PNLogVerbosity.BODY
}
// Initialize PubNub with the configuration
val pubnub = PubNub.create(config.build())
- logger.info("PubNub client initialized with BODY level logging")
-
// Perform some operations to generate logs
try {
// Get time operation
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messagePersistence/FetchMessagesMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messagePersistence/FetchMessagesMain.kt
index 6daf41922e..36453f60eb 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messagePersistence/FetchMessagesMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messagePersistence/FetchMessagesMain.kt
@@ -4,7 +4,6 @@ package com.pubnub.docs.messagePersistence
// snippet.fetchMessages
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.models.consumer.PNBoundedPage
import com.pubnub.api.models.consumer.history.PNFetchMessagesResult
import com.pubnub.api.v2.PNConfiguration
@@ -21,7 +20,6 @@ fun main() {
val userId = UserId("history-demo-user")
val config = PNConfiguration.builder(userId, "demo").apply {
publishKey = "demo"
- logVerbosity = PNLogVerbosity.BODY // Enable network calls logging
}.build()
// Create PubNub instance
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messageReactions/MessageReactionWithPagingMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messageReactions/MessageReactionWithPagingMain.kt
index 26e60f05b0..963d85f632 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messageReactions/MessageReactionWithPagingMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messageReactions/MessageReactionWithPagingMain.kt
@@ -5,7 +5,6 @@ package com.pubnub.docs.messageReactions
import com.pubnub.api.PubNub
import com.pubnub.api.PubNubException
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.models.consumer.PNBoundedPage
import com.pubnub.api.models.consumer.message_actions.PNGetMessageActionsResult
import com.pubnub.api.models.consumer.message_actions.PNMessageAction
@@ -15,7 +14,6 @@ fun main() {
val userId = UserId("message-action-demo-user")
val config = PNConfiguration.builder(userId, "demo").apply {
publishKey = "demo"
- logVerbosity = PNLogVerbosity.BODY // Enable debug logging for visibility
}.build()
val pubnub = PubNub.create(config)
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messageReactions/MessageReactionsMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messageReactions/MessageReactionsMain.kt
index 1a585ebbba..ae970e4859 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messageReactions/MessageReactionsMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/messageReactions/MessageReactionsMain.kt
@@ -4,7 +4,6 @@ package com.pubnub.docs.messageReactions
// snippet.messageReactionsMain
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.models.consumer.message_actions.PNMessageAction
import com.pubnub.api.v2.PNConfiguration
@@ -16,7 +15,6 @@ fun main() {
val userId = UserId("message-action-demo-user")
val config = PNConfiguration.builder(userId, "demo").apply {
publishKey = "demo"
- logVerbosity = PNLogVerbosity.BODY // Enable debug logging of network calls
}.build()
// 2. Create PubNub instance
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/miscellaneous/CreatePushPayloadMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/miscellaneous/CreatePushPayloadMain.kt
index ec9c322a97..449f425065 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/miscellaneous/CreatePushPayloadMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/miscellaneous/CreatePushPayloadMain.kt
@@ -4,7 +4,6 @@ package com.pubnub.docs.miscellaneous
// snippet.createPushPayloadMain
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.enums.PNPushEnvironment
import com.pubnub.api.models.consumer.push.payload.PushPayloadHelper
import com.pubnub.api.v2.PNConfiguration
@@ -26,7 +25,6 @@ fun main() {
val userId = UserId("push-helper-demo-user")
val config = PNConfiguration.builder(userId, "demo").apply {
publishKey = "demo"
- logVerbosity = PNLogVerbosity.BODY // Enable debug logging of network calls
}.build()
// 2. Create PubNub instance
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/mobilePush/AddPushNotificationsOnChannelsMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/mobilePush/AddPushNotificationsOnChannelsMain.kt
index f386f2da09..aa1506d27f 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/mobilePush/AddPushNotificationsOnChannelsMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/mobilePush/AddPushNotificationsOnChannelsMain.kt
@@ -2,7 +2,6 @@ package com.pubnub.docs.mobilePush
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.enums.PNPushEnvironment
import com.pubnub.api.enums.PNPushType
import com.pubnub.api.models.consumer.PNPublishResult
@@ -30,7 +29,6 @@ fun main() {
val userId = UserId("push-notifications-demo-user")
val config = PNConfiguration.builder(userId, "demo").apply {
publishKey = "demo"
- logVerbosity = PNLogVerbosity.BODY // Enable debug logging of network calls
}.build()
// 2. Create PubNub instance
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/presence/HereNowMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/presence/HereNowMain.kt
index 7e7f6ccf85..899ca616e9 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/presence/HereNowMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/presence/HereNowMain.kt
@@ -4,7 +4,6 @@ package com.pubnub.docs.presence
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.v2.PNConfiguration
fun main() {
@@ -15,7 +14,6 @@ fun main() {
val userId = UserId("here-now-demo-user")
val config = PNConfiguration.builder(userId, "demo").apply {
publishKey = "demo"
- logVerbosity = PNLogVerbosity.BODY // Enable debug logging of network calls
}.build()
// Create PubNub instance
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/publishAndSubscribe/publish/PublishMain.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/publishAndSubscribe/publish/PublishMain.kt
index 42bf8c1690..8e2f3672f8 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/publishAndSubscribe/publish/PublishMain.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/publishAndSubscribe/publish/PublishMain.kt
@@ -3,7 +3,6 @@ package com.pubnub.docs.publishAndSubscribe.publish
// snippet.publishMain
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.v2.PNConfiguration
fun main() {
@@ -14,7 +13,6 @@ fun main() {
val userId = UserId("publish-demo-user")
val config = PNConfiguration.builder(userId, "demo").apply {
publishKey = "demo"
- logVerbosity = PNLogVerbosity.BODY // Enable debug logging of network calls
}.build()
// Create PubNub instance
diff --git a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/publishAndSubscribe/subscribe/SubscribeOld.kt b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/publishAndSubscribe/subscribe/SubscribeOld.kt
index 18ff0abf99..b1f3d018aa 100644
--- a/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/publishAndSubscribe/subscribe/SubscribeOld.kt
+++ b/pubnub-kotlin/pubnub-kotlin-docs/src/main/kotlin/com/pubnub/docs/publishAndSubscribe/subscribe/SubscribeOld.kt
@@ -3,7 +3,6 @@ package com.pubnub.docs.publishAndSubscribe.subscribe
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
import com.pubnub.api.callbacks.SubscribeCallback
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.enums.PNStatusCategory
import com.pubnub.api.models.consumer.PNStatus
import com.pubnub.api.models.consumer.pubsub.PNPresenceEventResult
@@ -17,7 +16,6 @@ class SubscribeOld : SnippetBase() {
// snippet.subscribeWithLogging
val pnConfiguration = com.pubnub.api.v2.PNConfiguration.builder(UserId("myUserId"), "demo").apply {
publishKey = "my_pubkey"
- logVerbosity = PNLogVerbosity.BODY
}
val pubnub = PubNub.create(pnConfiguration.build())
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/build.gradle.kts b/pubnub-kotlin/pubnub-kotlin-impl/build.gradle.kts
index f784165af8..87b2ea090d 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/build.gradle.kts
+++ b/pubnub-kotlin/pubnub-kotlin-impl/build.gradle.kts
@@ -49,8 +49,6 @@ dependencies {
implementation(libs.cbor)
testImplementation(libs.wiremock)
- testImplementation(libs.logback.classic)
- testImplementation(libs.logback.core)
testImplementation(libs.cucumber.java)
testImplementation(libs.cucumber.junit)
testImplementation(libs.cucumber.picocontainer)
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/BaseIntegrationTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/BaseIntegrationTest.kt
index 20a33dc71f..3113aad141 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/BaseIntegrationTest.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/BaseIntegrationTest.kt
@@ -5,18 +5,15 @@ import com.pubnub.api.UserId
import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.retry.RetryConfiguration
import com.pubnub.api.v2.PNConfiguration
-import com.pubnub.test.CommonUtils.createInterceptor
import com.pubnub.test.Keys
+import okhttp3.logging.HttpLoggingInterceptor
import org.junit.After
import org.junit.Before
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
-import org.slf4j.LoggerFactory
import java.util.UUID
abstract class BaseIntegrationTest {
- protected val logger = LoggerFactory.getLogger(this.javaClass.simpleName)
-
val pubnub: PubNub by lazy { createPubNub() }
val server: PubNub by lazy { createServer() }
var clientConfig: PNConfiguration.Builder.() -> Unit = {}
@@ -95,7 +92,6 @@ abstract class BaseIntegrationTest {
}
clientConfig.retryConfiguration = RetryConfiguration.None
clientConfig.logVerbosity = PNLogVerbosity.NONE
- clientConfig.httpLoggingInterceptor = createInterceptor(logger)
return clientConfig
}
@@ -105,7 +101,7 @@ abstract class BaseIntegrationTest {
serverConfig.publishKey = Keys.pamPubKey
serverConfig.secretKey = Keys.pamSecKey
serverConfig.logVerbosity = PNLogVerbosity.NONE
- serverConfig.httpLoggingInterceptor = createInterceptor(logger)
+ serverConfig.httpLoggingInterceptor = HttpLoggingInterceptor()
serverConfig.action()
return serverConfig.build()
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/LoggingIntegrationTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/LoggingIntegrationTest.kt
new file mode 100644
index 0000000000..b8ae78e9e5
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/LoggingIntegrationTest.kt
@@ -0,0 +1,114 @@
+package com.pubnub.api.integration
+
+import com.pubnub.api.PubNub
+import com.pubnub.api.UserId
+import com.pubnub.api.logging.CustomLogger
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
+import com.pubnub.api.logging.LogMessageType
+import com.pubnub.api.v2.PNConfiguration
+import com.pubnub.test.CommonUtils.generatePayload
+import com.pubnub.test.CommonUtils.randomChannel
+import com.pubnub.test.Keys
+import org.junit.Assert.assertTrue
+import org.junit.Test
+
+class LoggingIntegrationTest : BaseIntegrationTest() {
+ @Test
+ fun testCanLogMessagesUsingCustomLogger() {
+ // Clear any previous messages
+ CustomLoggerTestImpl.clear()
+
+ val expectedUuid = PubNub.generateUUID()
+ val configBuilder = PNConfiguration.builder(UserId(expectedUuid), Keys.subKey) {
+ publishKey = Keys.pubKey
+ customLoggers = listOf(CustomLoggerTestImpl())
+ }
+ val pubNub = PubNub.create(configBuilder.build())
+
+ val expectedChannel = randomChannel()
+ pubNub.publish(
+ channel = expectedChannel,
+ message = generatePayload(),
+ customMessageType = "myType"
+ ).sync()
+
+ // Verify logging
+ assertTrue("Should have received string messages", CustomLoggerTestImpl.stringMessages.isNotEmpty())
+ assertTrue("Should have received LogMessage objects", CustomLoggerTestImpl.logMessages.isNotEmpty())
+
+ // Verify content
+ assertTrue(
+ "Should have called publish on the expected channel",
+ CustomLoggerTestImpl.stringMessages.any { msg ->
+ msg.contains("PublishEndpoint") && msg.contains(expectedChannel)
+ }
+ )
+
+ assertTrue(
+ "Should have called publish on the expected channel",
+ CustomLoggerTestImpl.stringMessages.any { msg ->
+ msg.contains("NetworkRequest") && msg.contains(expectedChannel)
+ }
+ )
+
+ assertTrue(
+ "Should have called publish on the expected channel",
+ CustomLoggerTestImpl.stringMessages.any { msg ->
+ msg.contains("NetworkResponse") && msg.contains(expectedChannel)
+ }
+ )
+
+ assertTrue(
+ "Should have called publish on the expected channel",
+ CustomLoggerTestImpl.logMessages.any { msg ->
+ msg.type == LogMessageType.OBJECT && msg.location!!.contains("PublishEndpoint") &&
+ (msg.message as? LogMessageContent.Object)?.message?.get("channel") == expectedChannel
+ }
+ )
+
+ assertTrue(
+ "Should have called publish API. LogMessage type should be NETWORK_REQUEST",
+ CustomLoggerTestImpl.logMessages.any { msg ->
+ msg.type == LogMessageType.NETWORK_REQUEST && msg.location!!.contains("publish")
+ }
+ )
+
+ assertTrue(
+ "Should have called publish API. LogMessage type should be NETWORK_RESPONSE",
+ CustomLoggerTestImpl.logMessages.any { msg ->
+ msg.type == LogMessageType.NETWORK_RESPONSE && msg.location!!.contains("publish")
+ }
+ )
+ }
+
+ class CustomLoggerTestImpl : CustomLogger {
+ override val name: String = "CustomLoggerTestImpl"
+
+ override fun trace(message: String?) {
+ stringMessages.add(message ?: "")
+ }
+
+ override fun trace(message: LogMessage) {
+ logMessages.add(message)
+ }
+
+ override fun debug(message: String?) {
+ stringMessages.add(message ?: "")
+ }
+
+ override fun debug(logMessage: LogMessage) {
+ logMessages.add(logMessage)
+ }
+
+ companion object {
+ val stringMessages = mutableListOf()
+ val logMessages = mutableListOf()
+
+ fun clear() {
+ stringMessages.clear()
+ logMessages.clear()
+ }
+ }
+ }
+}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PNConfigurationIntegrationTests.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PNConfigurationIntegrationTests.kt
index 7b1d56e874..624ebaf542 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PNConfigurationIntegrationTests.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PNConfigurationIntegrationTests.kt
@@ -2,6 +2,8 @@ package com.pubnub.api.integration
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
+import com.pubnub.api.enums.PNLogVerbosity
+import com.pubnub.api.integration.LoggingIntegrationTest.CustomLoggerTestImpl
import com.pubnub.api.v2.PNConfiguration
import com.pubnub.api.v2.PNConfigurationOverride
import com.pubnub.test.CommonUtils.randomChannel
@@ -34,6 +36,8 @@ class PNConfigurationIntegrationTests : BaseIntegrationTest() {
val configBuilder = PNConfiguration.builder(UserId(expectedUuid), Keys.subKey) {
publishKey = Keys.pubKey
authToken = expectedAuthToken
+ logVerbosity = PNLogVerbosity.NONE
+ customLoggers = listOf(CustomLoggerTestImpl())
}
val pubNub = PubNub.create(configBuilder.build())
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PublishIntegrationTests.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PublishIntegrationTests.kt
index 1f91e5afd2..0bbb45aedc 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PublishIntegrationTests.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PublishIntegrationTests.kt
@@ -7,6 +7,7 @@ import com.pubnub.api.UserId
import com.pubnub.api.callbacks.SubscribeCallback
import com.pubnub.api.crypto.CryptoModule
import com.pubnub.api.enums.PNStatusCategory
+import com.pubnub.api.logging.LogConfig
import com.pubnub.api.models.consumer.PNBoundedPage
import com.pubnub.api.models.consumer.PNPublishResult
import com.pubnub.api.models.consumer.PNStatus
@@ -80,6 +81,7 @@ class PublishIntegrationTests : BaseIntegrationTest() {
@Test
fun testPublishMessageHistory() {
+ val logConfig = LogConfig("testPnInstanceId", "testUserId")
val expectedChannel = randomChannel()
val expectedPayload =
@@ -88,7 +90,7 @@ class PublishIntegrationTests : BaseIntegrationTest() {
addProperty("age", 48)
}
- val convertedPayload = MapperManager().convertValue(expectedPayload, JsonObject::class.java)
+ val convertedPayload = MapperManager(logConfig).convertValue(expectedPayload, JsonObject::class.java)
pubnub.publish(
channel = expectedChannel,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PushIntegrationTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PushIntegrationTest.kt
index db092e9aad..2f14c6a75b 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PushIntegrationTest.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PushIntegrationTest.kt
@@ -39,10 +39,10 @@ class PushIntegrationTest : BaseIntegrationTest() {
}
private fun runPushOperations(pushType: PNPushType) {
- logger.info("Push type '$pushType'")
- logger.info("Channels $expectedChannels'")
- logger.info("Topic $expectedTopic'")
- logger.info("GeneratedToken '${expectedDeviceId.length}': $expectedDeviceId")
+ println("Push type '$pushType'")
+ println("Channels $expectedChannels'")
+ println("Topic $expectedTopic'")
+ println("GeneratedToken '${expectedDeviceId.length}': $expectedDeviceId")
pubnub.addPushNotificationsOnChannels(
channels = expectedChannels,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/pam/GrantTokenIntegrationTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/pam/GrantTokenIntegrationTest.kt
index 28e3c73351..eea0dba3a5 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/pam/GrantTokenIntegrationTest.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/pam/GrantTokenIntegrationTest.kt
@@ -155,7 +155,6 @@ class GrantTokenIntegrationTest : BaseIntegrationTest() {
subscribeKey = Keys.pamSubKey
publishKey = Keys.pamPubKey
logVerbosity = PNLogVerbosity.NONE
- httpLoggingInterceptor = CommonUtils.createInterceptor(logger)
}
// setToken
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/EndpointCore.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/EndpointCore.kt
index b0ff828613..aef7f8cda4 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/EndpointCore.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/EndpointCore.kt
@@ -10,12 +10,13 @@ import com.pubnub.api.v2.PNConfiguration.Companion.isValid
import com.pubnub.api.v2.PNConfigurationOverride
import com.pubnub.api.v2.callbacks.Consumer
import com.pubnub.api.v2.callbacks.Result
+import com.pubnub.internal.logging.ConfigurationLogger.logConfiguration
+import com.pubnub.internal.logging.LoggerManager
import com.pubnub.internal.managers.RetrofitManager
import com.pubnub.internal.retry.RetryableBase
import com.pubnub.internal.retry.RetryableCallback
import com.pubnub.internal.retry.RetryableRestCaller
import com.pubnub.internal.v2.PNConfigurationImpl
-import org.slf4j.LoggerFactory
import retrofit2.Call
import retrofit2.Response
import java.io.IOException
@@ -40,7 +41,7 @@ abstract class EndpointCore protected constructor(protected val p
RetrofitManager(pubnub.retrofitManager, configOverrideNonNull)
} ?: pubnub.retrofitManager
- private val log = LoggerFactory.getLogger(this.javaClass.simpleName)
+ private val logger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
private lateinit var cachedCallback: Consumer>
private lateinit var call: Call
@@ -50,6 +51,7 @@ abstract class EndpointCore protected constructor(protected val p
configuration.retryConfiguration,
getEndpointGroupName(),
isEndpointRetryable(),
+ pubnub.logConfig
)
}
@@ -119,6 +121,7 @@ abstract class EndpointCore protected constructor(protected val p
endpointGroupName = getEndpointGroupName(),
isEndpointRetryable = isEndpointRetryable(),
executorService = pubnub.executorService,
+ logConfig = pubnub.logConfig
) {
override fun onFinalResponse(
call: Call,
@@ -439,6 +442,7 @@ abstract class EndpointCore protected constructor(protected val p
}
fun overrideConfigurationInternal(configuration: PNConfiguration) {
+ logConfiguration(configuration = configuration, logger = logger, instanceId = pubnub.instanceId, className = this::class.java)
this.configOverride = configuration
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt
index e9aecc6d1b..0b5e8cafa4 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt
@@ -52,6 +52,10 @@ import com.pubnub.api.endpoints.push.RemoveAllPushChannelsForDevice
import com.pubnub.api.endpoints.push.RemoveChannelsFromPush
import com.pubnub.api.enums.PNPushEnvironment
import com.pubnub.api.enums.PNPushType
+import com.pubnub.api.logging.ErrorDetails
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.PNBoundedPage
import com.pubnub.api.models.consumer.access_manager.sum.SpacePermissions
import com.pubnub.api.models.consumer.access_manager.sum.UserPermissions
@@ -89,6 +93,7 @@ import com.pubnub.api.v2.subscriptions.Subscription
import com.pubnub.api.v2.subscriptions.SubscriptionCursor
import com.pubnub.api.v2.subscriptions.SubscriptionOptions
import com.pubnub.api.v2.subscriptions.SubscriptionSet
+import com.pubnub.internal.crypto.CryptoModuleImpl
import com.pubnub.internal.crypto.decryptString
import com.pubnub.internal.crypto.encryptString
import com.pubnub.internal.endpoints.DeleteMessagesEndpoint
@@ -139,6 +144,9 @@ import com.pubnub.internal.endpoints.push.AddChannelsToPushEndpoint
import com.pubnub.internal.endpoints.push.ListPushProvisionsEndpoint
import com.pubnub.internal.endpoints.push.RemoveAllPushChannelsForDeviceEndpoint
import com.pubnub.internal.endpoints.push.RemoveChannelsFromPushEndpoint
+import com.pubnub.internal.logging.ConfigurationLogger.logConfiguration
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.managers.BasePathManager
import com.pubnub.internal.managers.DuplicationManager
import com.pubnub.internal.managers.ListenerManager
@@ -154,6 +162,7 @@ import com.pubnub.internal.presence.eventengine.effect.effectprovider.LeaveProvi
import com.pubnub.internal.subscribe.PRESENCE_CHANNEL_SUFFIX
import com.pubnub.internal.subscribe.Subscribe
import com.pubnub.internal.subscribe.eventengine.configuration.EventEnginesConf
+import com.pubnub.internal.v2.PNConfigurationImpl
import com.pubnub.internal.v2.entities.ChannelGroupImpl
import com.pubnub.internal.v2.entities.ChannelGroupName
import com.pubnub.internal.v2.entities.ChannelImpl
@@ -180,20 +189,34 @@ open class PubNubImpl(
val pnsdkName: String = PNSDK_PUBNUB_KOTLIN,
eventEnginesConf: EventEnginesConf = EventEnginesConf()
) : PubNub {
+ protected val logger: PNLogger by lazy { LoggerManager.instance.getLogger(logConfig, this::class.java) }
internal val tokenManager: TokenManager = TokenManager()
init {
this.setToken(configuration.authToken)
}
+
constructor(configuration: PNConfiguration) : this(configuration, PNSDK_PUBNUB_KOTLIN)
- val mapper = MapperManager()
+ /**
+ * Unique id of this PubNub instance.
+ *
+ * @see [PNConfiguration.includeInstanceIdentifier]
+ */
+ val instanceId = UUID.randomUUID().toString()
+ val logConfig: LogConfig = LogConfig(
+ pnInstanceId = instanceId,
+ userId = configuration.userId.value,
+ customLoggers = configuration.customLoggers,
+ )
+
+ val mapper = MapperManager(logConfig)
private val numberOfThreadsInPool = Integer.min(Runtime.getRuntime().availableProcessors(), 8)
internal val executorService: ScheduledExecutorService = Executors.newScheduledThreadPool(numberOfThreadsInPool)
val listenerManager: ListenerManager = ListenerManager(this)
private val basePathManager = BasePathManager(configuration)
- internal val retrofitManager = RetrofitManager(this, configuration)
+ internal val retrofitManager = RetrofitManager(pubnub = this, configuration = configuration)
internal val publishSequenceManager = PublishSequenceManager(MAX_SEQUENCE)
private val tokenParser: TokenParser = TokenParser()
private val presenceData = PresenceData()
@@ -202,7 +225,7 @@ open class PubNubImpl(
this,
listenerManager,
eventEnginesConf,
- SubscribeMessageProcessor(this, DuplicationManager(configuration)),
+ SubscribeMessageProcessor(this, DuplicationManager(configuration), logConfig),
presenceData,
configuration.maintainPresenceState,
)
@@ -219,14 +242,34 @@ open class PubNubImpl(
presenceData = presenceData,
sendStateWithHeartbeat = configuration.maintainPresenceState,
executorService = executorService,
+ logConfig = logConfig,
)
- /**
- * Unique id of this PubNub instance.
- *
- * @see [PNConfiguration.includeInstanceIdentifier]
- */
- val instanceId = UUID.randomUUID().toString()
+ internal val cryptoModuleWithLogConfig: CryptoModule? by lazy {
+ when (configuration) {
+ is PNConfigurationImpl -> (configuration as PNConfigurationImpl).getCryptoModuleWithLogConfig(logConfig)
+ else -> {
+ // Try to call getCryptoModuleWithLogConfig using reflection for Java implementation
+ try {
+ val method = configuration.javaClass.getMethod("getCryptoModuleWithLogConfig", LogConfig::class.java)
+ method.invoke(configuration, logConfig) as? CryptoModule
+ } catch (e: Exception) {
+ logger.error(
+ LogMessage(
+ message = LogMessageContent.Error(
+ message = ErrorDetails(
+ type = e.javaClass.simpleName,
+ message = "Failed calling getCryptoModuleWithLogConfig"
+ )
+ ),
+ details = "details",
+ )
+ )
+ null
+ }
+ }
+ }
+ }
//region Internal
internal fun baseUrl() = basePathManager.basePath()
@@ -276,6 +319,15 @@ open class PubNubImpl(
fun generateUUID() = "pn-${UUID.randomUUID()}"
}
+ init {
+ logConfiguration(
+ configuration = configuration,
+ logger = logger,
+ instanceId = instanceId,
+ className = this::class.java
+ )
+ }
+
override fun subscriptionSetOf(
channels: Set,
channelGroups: Set,
@@ -372,7 +424,17 @@ open class PubNubImpl(
meta: Any?,
usePost: Boolean,
ttl: Int?,
- ): Publish = fire(channel, message, meta, usePost)
+ ): Publish {
+ logger.warn(
+ LogMessage(
+ message = LogMessageContent.Text(
+ "DEPRECATED: fire() with ttl parameter is deprecated. Use fire(channel, message, meta, usePost) instead."
+ ),
+ details = "The ttl parameter is not used and this method will be removed in a future version",
+ )
+ )
+ return fire(channel, message, meta, usePost)
+ }
override fun signal(
channel: String,
@@ -453,6 +515,14 @@ open class PubNubImpl(
includeTimetoken: Boolean,
includeMeta: Boolean,
): History {
+ logger.warn(
+ LogMessage(
+ message = LogMessageContent.Text(
+ "DEPRECATED: history() is deprecated. Use fetchMessages() instead."
+ ),
+ details = "This method will be removed in a future version",
+ )
+ )
return HistoryEndpoint(
pubnub = this,
channel = channel,
@@ -1450,6 +1520,7 @@ open class PubNubImpl(
includeUserType = includeUUIDType,
)
}
+
PNUUIDDetailsLevel.UUID_WITH_CUSTOM -> {
IncludeQueryParam(
includeCustom = includeCustom,
@@ -1458,6 +1529,7 @@ open class PubNubImpl(
includeUserType = includeUUIDType,
)
}
+
null -> IncludeQueryParam(includeCustom = includeCustom, includeUserType = includeUUIDType)
}
return ManageChannelMembersEndpoint(
@@ -1523,9 +1595,9 @@ open class PubNubImpl(
): SendFile {
val cryptoModule =
if (cipherKey != null) {
- CryptoModule.createLegacyCryptoModule(cipherKey)
+ createCryptoModuleWithLogConfig(CryptoModule.createLegacyCryptoModule(cipherKey))
} else {
- configuration.cryptoModule
+ cryptoModuleWithLogConfig
}
return SendFileEndpoint(
channel = channel,
@@ -1581,9 +1653,9 @@ open class PubNubImpl(
): DownloadFile {
val cryptoModule =
if (cipherKey != null) {
- CryptoModule.createLegacyCryptoModule(cipherKey)
+ createCryptoModuleWithLogConfig(CryptoModule.createLegacyCryptoModule(cipherKey))
} else {
- configuration.cryptoModule
+ cryptoModuleWithLogConfig
}
return DownloadFileEndpoint(
pubNub = this,
@@ -1645,8 +1717,10 @@ open class PubNubImpl(
)
private fun getCryptoModuleOrThrow(cipherKey: String? = null): CryptoModule {
- return cipherKey?.let { cipherKeyNotNull -> CryptoModule.createLegacyCryptoModule(cipherKeyNotNull) }
- ?: configuration.cryptoModule ?: throw PubNubException("Crypto module is not initialized")
+ return cipherKey?.let { cipherKeyNotNull ->
+ createCryptoModuleWithLogConfig(CryptoModule.createLegacyCryptoModule(cipherKeyNotNull))
+ }
+ ?: cryptoModuleWithLogConfig ?: throw PubNubException("Crypto module is not initialized")
}
@Throws(PubNubException::class)
@@ -1965,6 +2039,20 @@ open class PubNubImpl(
@Throws(PubNubException::class)
private fun getCryptoModuleOrThrow(cryptoModule: CryptoModule? = null): CryptoModule {
- return cryptoModule ?: configuration.cryptoModule ?: throw PubNubException("Crypto module is not initialized")
+ return cryptoModule?.let { createCryptoModuleWithLogConfig(it) } ?: cryptoModuleWithLogConfig
+ ?: throw PubNubException("Crypto module is not initialized")
+ }
+
+ private fun createCryptoModuleWithLogConfig(cryptoModule: CryptoModule): CryptoModule {
+ return if (cryptoModule is CryptoModuleImpl) {
+ CryptoModuleImpl(
+ primaryCryptor = cryptoModule.primaryCryptor,
+ cryptorsForDecryptionOnly = cryptoModule.cryptorsForDecryptionOnly,
+ logConfig = logConfig
+ )
+ } else {
+ // For custom implementations, return the original instance
+ cryptoModule
+ }
}
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubUtil.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubUtil.kt
index cf128d2bcd..b0a1f3ce1a 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubUtil.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubUtil.kt
@@ -5,7 +5,6 @@ import com.pubnub.api.v2.PNConfiguration
import com.pubnub.api.v2.PNConfiguration.Companion.isValid
import okhttp3.Request
import okio.Buffer
-import org.slf4j.LoggerFactory
import java.io.IOException
import java.io.UnsupportedEncodingException
import java.net.URLDecoder
@@ -19,8 +18,6 @@ import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
internal object PubNubUtil {
- private val log = LoggerFactory.getLogger("PubNubUtil")
-
private const val CHARSET = "UTF-8"
const val SIGNATURE_QUERY_PARAM_NAME = "signature"
const val TIMESTAMP_QUERY_PARAM_NAME = "timestamp"
@@ -128,9 +125,9 @@ internal object PubNubUtil {
signature = "v2.$signature"
}
} catch (e: PubNubException) {
- log.warn("signature failed on SignatureInterceptor: $e")
+ // do nothing
} catch (e: UnsupportedEncodingException) {
- log.warn("signature failed on SignatureInterceptor: $e")
+ // do nothing
}
return signature
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/crypto/CryptoModuleImpl.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/crypto/CryptoModuleImpl.kt
index 04390fd15e..58e37758b7 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/crypto/CryptoModuleImpl.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/crypto/CryptoModuleImpl.kt
@@ -6,56 +6,84 @@ import com.pubnub.api.crypto.CryptoModule
import com.pubnub.api.crypto.cryptor.Cryptor
import com.pubnub.api.crypto.data.EncryptedData
import com.pubnub.api.crypto.data.EncryptedStreamData
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.internal.crypto.cryptor.HeaderParser
import com.pubnub.internal.crypto.cryptor.LEGACY_CRYPTOR_ID
import com.pubnub.internal.crypto.cryptor.ParseResult
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import java.io.BufferedInputStream
import java.io.InputStream
import java.io.SequenceInputStream
private const val SIZE_OF_CRYPTOR_ID = 4
-class CryptoModuleImpl internal constructor(
+/**
+ * Public constructor for internal cross-module access only.
+ * This class is in an internal package and should not be used directly by consumers.
+ * Use CryptoModule factory methods instead.
+ */
+class CryptoModuleImpl(
@get:JvmSynthetic
- internal val primaryCryptor: Cryptor,
+ val primaryCryptor: Cryptor,
@get:JvmSynthetic
- internal val cryptorsForDecryptionOnly: List = listOf(),
+ val cryptorsForDecryptionOnly: List = listOf(),
+ @get:JvmSynthetic
+ val logConfig: LogConfig? = null,
) : CryptoModule {
- private val headerParser: HeaderParser = HeaderParser()
+ private val log: PNLogger by lazy {
+ logConfig?.let { LoggerManager.instance.getLogger(it, this::class.java) }
+ ?: LoggerManager.instance.getLogger(LogConfig("default", "default"), this::class.java)
+ }
+
+ private val headerParser: HeaderParser = HeaderParser(logConfig)
override fun encrypt(data: ByteArray): ByteArray {
+ logDebugMessage("Encrypting data of size: ${data.size} bytes")
+
val cryptorId = primaryCryptor.id()
validateData(data)
validateCryptorIdSize(cryptorId)
val (metadata, encryptedData) = primaryCryptor.encrypt(data)
- return if (cryptorId.contentEquals(LEGACY_CRYPTOR_ID)) {
+ val result = if (cryptorId.contentEquals(LEGACY_CRYPTOR_ID)) {
encryptedData
} else {
val cryptorHeader = headerParser.createCryptorHeader(cryptorId, metadata)
cryptorHeader + encryptedData
}
+ logDebugMessage("Encrypting successful")
+ return result
}
override fun decrypt(encryptedData: ByteArray): ByteArray {
+ logDebugMessage("Decrypting data of size: ${encryptedData.size} bytes")
+
validateData(encryptedData)
val parsedData: ParseResult = headerParser.parseDataWithHeader(encryptedData)
val decryptedData: ByteArray =
when (parsedData) {
is ParseResult.NoHeader -> {
+ logDebugMessage("Using legacy cryptor for decryption")
getDecryptedDataForLegacyCryptor(encryptedData)
}
is ParseResult.Success -> {
+ logDebugMessage("Using cryptor with header for decryption")
getDecryptedDataForCryptorWithHeader(parsedData)
}
}
+ logDebugMessage("Decryption successful")
return decryptedData
}
override fun encryptStream(stream: InputStream): InputStream {
+ logDebugMessage("Encrypting stream")
val bufferedInputStream = validateStreamAndReturnBuffered(stream)
val (metadata, encryptedData) = primaryCryptor.encryptStream(bufferedInputStream)
+ logDebugMessage("Encrypting stream successful")
return if (primaryCryptor.id().contentEquals(LEGACY_CRYPTOR_ID)) {
encryptedData
} else {
@@ -65,6 +93,7 @@ class CryptoModuleImpl internal constructor(
}
override fun decryptStream(encryptedData: InputStream): InputStream {
+ logDebugMessage("Decrypting stream")
val bufferedInputStream = validateStreamAndReturnBuffered(encryptedData)
return when (val parsedHeader = headerParser.parseDataWithHeader(bufferedInputStream)) {
ParseResult.NoHeader -> {
@@ -90,6 +119,10 @@ class CryptoModuleImpl internal constructor(
}
}
+ private fun logDebugMessage(message: String) {
+ log.debug(LogMessage(message = LogMessageContent.Text(message)))
+ }
+
private fun validateCryptorIdSize(cryptorId: ByteArray) {
if (cryptorId.size != SIZE_OF_CRYPTOR_ID) {
throw PubNubException(
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/crypto/cryptor/HeaderParser.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/crypto/cryptor/HeaderParser.kt
index 032c59c3ba..d0610e8b74 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/crypto/cryptor/HeaderParser.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/crypto/cryptor/HeaderParser.kt
@@ -2,8 +2,11 @@ package com.pubnub.internal.crypto.cryptor
import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.internal.crypto.readExactlyNBytez
-import org.slf4j.LoggerFactory
+import com.pubnub.internal.logging.LoggerManager
import java.io.BufferedInputStream
import java.io.InputStream
@@ -24,8 +27,13 @@ private const val THREE_BYTES_CRYPTOR_DATA_SIZE_ENDING_INDEX = 11
private const val MAX_VALUE_THAT_CAN_BE_STORED_ON_TWO_BYTES = 65535
private const val MINIMAL_SIZE_OF_CRYPTO_HEADER = 10
-internal class HeaderParser {
- private val log = LoggerFactory.getLogger(HeaderParser::class.java)
+internal class HeaderParser(val logConfig: LogConfig?) {
+ private val log = logConfig?.let {
+ LoggerManager.instance.getLogger(logConfig = it, clazz = this::class.java)
+ } ?: LoggerManager.instance.getLogger(
+ logConfig = LogConfig("default", "default"),
+ clazz = this::class.java
+ )
fun parseDataWithHeader(stream: BufferedInputStream): ParseResult {
val bufferedInputStream = stream.buffered()
@@ -81,8 +89,7 @@ internal class HeaderParser {
if (data.size < MINIMAL_SIZE_OF_DATA_HAVING_CRYPTOR_HEADER) {
throw PubNubException(
- errorMessage =
- "Minimal size of encrypted data having Cryptor Data Header is: $MINIMAL_SIZE_OF_DATA_HAVING_CRYPTOR_HEADER",
+ errorMessage = "Minimal size of encrypted data having Cryptor Data Header is: $MINIMAL_SIZE_OF_DATA_HAVING_CRYPTOR_HEADER",
pubnubError = PubNubError.CRYPTOR_DATA_HEADER_SIZE_TO_SMALL,
)
}
@@ -90,7 +97,7 @@ internal class HeaderParser {
validateCryptorHeaderVersion(data)
val cryptorId = data.sliceArray(CRYPTOR_ID_STARTING_INDEX..CRYPTOR_ID_ENDING_INDEX)
- log.trace("CryptoId: ${String(cryptorId, Charsets.UTF_8)}")
+ logTraceMessage("CryptoId: ${String(cryptorId, Charsets.UTF_8)}")
val cryptorDataSizeFirstByte: Byte = data[CRYPTOR_DATA_SIZE_STARTING_INDEX]
val (startingIndexOfCryptorData, cryptorDataSize) =
@@ -128,9 +135,7 @@ internal class HeaderParser {
byteArrayOf(cryptorDataSize.toByte()) + writeNumberOnTwoBytes(cryptorDataSize)
} else {
throw PubNubException(
- errorMessage =
- "Cryptor Data Size is: $cryptorDataSize whereas " +
- "max cryptor data size is: $MAX_VALUE_THAT_CAN_BE_STORED_ON_TWO_BYTES",
+ errorMessage = "Cryptor Data Size is: $cryptorDataSize whereas max cryptor data size is: $MAX_VALUE_THAT_CAN_BE_STORED_ON_TWO_BYTES",
pubnubError = PubNubError.CRYPTOR_HEADER_PARSE_ERROR,
)
}
@@ -154,14 +159,14 @@ internal class HeaderParser {
if (cryptoDataFirstByteAsUByte == THREE_BYTES_SIZE_CRYPTOR_DATA_INDICATOR) {
startingIndexOfCryptorData = STARTING_INDEX_OF_THREE_BYTES_CRYPTOR_DATA_SIZE
- log.trace("\"Cryptor data size\" first byte's value is 255 that mean that size is stored on two next bytes")
+ logTraceMessage("\"Cryptor data size\" first byte's value is 255 that mean that size is stored on two next bytes")
val cryptorDataSizeSecondByte = data[THREE_BYTES_CRYPTOR_DATA_SIZE_STARTING_INDEX]
val cryptorDataSizeThirdByte = data[THREE_BYTES_CRYPTOR_DATA_SIZE_ENDING_INDEX]
cryptorDataSize = convertTwoBytesToIntBigEndian(cryptorDataSizeSecondByte, cryptorDataSizeThirdByte)
} else {
startingIndexOfCryptorData = STARTING_INDEX_OF_ONE_BYTE_CRYPTOR_DATA_SIZE
cryptorDataSize = cryptoDataFirstByteAsUByte.toInt()
- log.trace("\"Cryptor data size\" is 1 byte long and its value is: $cryptorDataSize")
+ logTraceMessage("\"Cryptor data size\" is 1 byte long and its value is: $cryptorDataSize")
}
return Pair(startingIndexOfCryptorData, cryptorDataSize)
}
@@ -169,7 +174,7 @@ internal class HeaderParser {
private fun validateCryptorHeaderVersion(data: ByteArray) {
val version: UByte = data[VERSION_INDEX].toUByte() // 5th byte
val versionAsInt = version.toInt()
- log.trace("Cryptor header version is: $versionAsInt")
+ logTraceMessage("Cryptor header version is: $versionAsInt")
// check if version exist in this SDK version
CryptorHeaderVersion.fromValue(versionAsInt)
?: throw PubNubException(
@@ -178,6 +183,10 @@ internal class HeaderParser {
)
}
+ private fun logTraceMessage(message: String) {
+ log.trace(LogMessage(message = LogMessageContent.Text(message)))
+ }
+
private fun convertTwoBytesToIntBigEndian(
byte1: Byte,
byte2: Byte,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/DeleteMessagesEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/DeleteMessagesEndpoint.kt
index b9132d07d6..afde56ef4b 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/DeleteMessagesEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/DeleteMessagesEndpoint.kt
@@ -4,10 +4,14 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.DeleteMessages
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.history.PNDeleteMessagesResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.toCsv
import retrofit2.Call
import retrofit2.Response
@@ -22,6 +26,8 @@ class DeleteMessagesEndpoint internal constructor(
override val start: Long? = null,
override val end: Long? = null,
) : EndpointCore(pubnub), DeleteMessages {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun validateParams() {
super.validateParams()
if (channels.isEmpty()) {
@@ -30,6 +36,20 @@ class DeleteMessagesEndpoint internal constructor(
}
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channels" to channels,
+ "start" to (start ?: ""),
+ "end" to (end ?: ""),
+ "queryParams" to queryParams
+ )
+ ),
+ details = "DeleteMessages API call",
+ )
+ )
+
addQueryParams(queryParams)
return retrofitManager.historyService.deleteMessages(
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/FetchMessagesEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/FetchMessagesEndpoint.kt
index 46bd3d4342..c884441ba9 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/FetchMessagesEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/FetchMessagesEndpoint.kt
@@ -4,6 +4,8 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.FetchMessages
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.PNBoundedPage
import com.pubnub.api.models.consumer.history.HistoryMessageType
import com.pubnub.api.models.consumer.history.PNFetchMessageItem
@@ -14,6 +16,8 @@ import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.extension.limit
import com.pubnub.internal.extension.nonPositiveToNull
import com.pubnub.internal.extension.tryDecryptMessage
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.FetchMessagesEnvelope
import com.pubnub.internal.models.server.history.ServerFetchMessageItem
import com.pubnub.internal.toCsv
@@ -34,6 +38,8 @@ class FetchMessagesEndpoint internal constructor(
override val includeMessageType: Boolean = false,
override val includeCustomMessageType: Boolean = false
) : EndpointCore(pubnub), FetchMessages {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
internal companion object {
private const val SINGLE_CHANNEL_DEFAULT_MESSAGES = 100
private const val SINGLE_CHANNEL_MAX_MESSAGES = 100
@@ -77,6 +83,24 @@ class FetchMessagesEndpoint internal constructor(
override fun getAffectedChannels() = channels
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channels" to channels,
+ "page" to page,
+ "includeUUID" to includeUUID,
+ "includeMeta" to includeMeta,
+ "includeMessageActions" to includeMessageActions,
+ "includeMessageType" to includeMessageType,
+ "includeCustomMessageType" to includeCustomMessageType,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "FetchMessages API call",
+ )
+ )
+
addQueryParams(queryParams)
return if (!includeMessageActions) {
@@ -101,8 +125,9 @@ class FetchMessagesEndpoint internal constructor(
value.map { serverMessageItem: ServerFetchMessageItem ->
val (newMessage, error) =
serverMessageItem.message.tryDecryptMessage(
- configuration.cryptoModule,
+ pubnub.cryptoModuleWithLogConfig,
pubnub.mapper,
+ log,
)
val newActions =
if (includeMessageActions) {
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/HistoryEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/HistoryEndpoint.kt
index c869a37608..b9ce161006 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/HistoryEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/HistoryEndpoint.kt
@@ -5,12 +5,16 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.History
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.history.PNHistoryItemResult
import com.pubnub.api.models.consumer.history.PNHistoryResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.extension.tryDecryptMessage
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import retrofit2.Call
import retrofit2.Response
import java.util.Locale
@@ -28,6 +32,7 @@ class HistoryEndpoint internal constructor(
override val includeTimetoken: Boolean,
override val includeMeta: Boolean,
) : EndpointCore(pubnub), History {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
private val countParam: Int =
if (count in 1..PNHistoryResult.MAX_COUNT) {
count
@@ -45,6 +50,24 @@ class HistoryEndpoint internal constructor(
override fun getAffectedChannels() = listOf(channel)
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "start" to (start ?: ""),
+ "end" to (end ?: ""),
+ "count" to count,
+ "reverse" to reverse,
+ "includeTimetoken" to includeTimetoken,
+ "includeMeta" to includeMeta,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "History API call",
+ )
+ )
+
addQueryParams(queryParams)
return retrofitManager.historyService.fetchHistory(
@@ -81,7 +104,7 @@ class HistoryEndpoint internal constructor(
if (includeTimetoken || includeMeta) {
historyMessageWithError =
pubnub.mapper.getField(historyEntry, "message")!!
- .tryDecryptMessage(configuration.cryptoModule, pubnub.mapper)
+ .tryDecryptMessage(pubnub.cryptoModuleWithLogConfig, pubnub.mapper, log)
if (includeTimetoken) {
timetoken = pubnub.mapper.elementToLong(historyEntry, "timetoken")
}
@@ -89,7 +112,11 @@ class HistoryEndpoint internal constructor(
meta = pubnub.mapper.getField(historyEntry, "meta")
}
} else {
- historyMessageWithError = historyEntry.tryDecryptMessage(configuration.cryptoModule, pubnub.mapper)
+ historyMessageWithError = historyEntry.tryDecryptMessage(
+ pubnub.cryptoModuleWithLogConfig,
+ pubnub.mapper,
+ log,
+ )
}
val message: JsonElement = historyMessageWithError.first
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/MessageCountsEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/MessageCountsEndpoint.kt
index ab8a7b8e09..4654ea4f23 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/MessageCountsEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/MessageCountsEndpoint.kt
@@ -5,10 +5,14 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.MessageCounts
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.history.PNMessageCountResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.toCsv
import retrofit2.Call
import retrofit2.Response
@@ -21,6 +25,8 @@ class MessageCountsEndpoint internal constructor(
override val channels: List,
override val channelsTimetoken: List,
) : EndpointCore(pubnub), MessageCounts {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun validateParams() {
super.validateParams()
if (channels.isEmpty()) {
@@ -37,6 +43,19 @@ class MessageCountsEndpoint internal constructor(
override fun getAffectedChannels() = channels
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channels" to channels,
+ "channelsTimetoken" to channelsTimetoken,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "MessageCounts API call",
+ )
+ )
+
addQueryParams(queryParams)
return retrofitManager.historyService.fetchCount(
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/TimeEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/TimeEndpoint.kt
index edfee085cf..567042dcee 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/TimeEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/TimeEndpoint.kt
@@ -2,10 +2,15 @@ package com.pubnub.internal.endpoints
import com.pubnub.api.endpoints.Time
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.PNTimeResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
+import retrofit2.Call
import retrofit2.Response
/**
@@ -14,11 +19,27 @@ import retrofit2.Response
class TimeEndpoint(pubnub: PubNubImpl, private val excludeFromRetry: Boolean = false) :
EndpointCore, PNTimeResult>(pubnub),
Time {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun getAffectedChannels() = emptyList()
override fun getAffectedChannelGroups() = emptyList()
- override fun doWork(queryParams: HashMap) = retrofitManager.timeService.fetchTime(queryParams)
+ override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "excludeFromRetry" to excludeFromRetry,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "Time API call",
+ )
+ )
+
+ return retrofitManager.timeService.fetchTime(queryParams)
+ }
override fun createResponse(input: Response>): PNTimeResult {
return PNTimeResult(input.body()!![0])
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/access/GrantEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/access/GrantEndpoint.kt
index 8210e8451b..ddcae74f48 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/access/GrantEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/access/GrantEndpoint.kt
@@ -5,12 +5,16 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.access.Grant
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.access_manager.PNAccessManagerGrantResult
import com.pubnub.api.models.consumer.access_manager.PNAccessManagerKeyData
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.api.v2.PNConfiguration.Companion.isValid
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.Envelope
import com.pubnub.internal.models.server.access_manager.AccessManagerGrantPayload
import com.pubnub.internal.toCsv
@@ -35,6 +39,8 @@ open class GrantEndpoint(
override val channelGroups: List = emptyList(),
override val uuids: List = emptyList(),
) : EndpointCore, PNAccessManagerGrantResult>(pubnub), Grant {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun validateParams() {
super.validateParams()
if (!pubnub.configuration.secretKey.isValid()) {
@@ -47,6 +53,29 @@ open class GrantEndpoint(
override fun getAffectedChannelGroups() = channelGroups
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "read" to read,
+ "write" to write,
+ "manage" to manage,
+ "delete" to delete,
+ "get" to get,
+ "update" to update,
+ "join" to join,
+ "ttl" to ttl,
+ "authKeys" to authKeys,
+ "channels" to channels,
+ "channelGroups" to channelGroups,
+ "uuids" to uuids,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "Grant API call",
+ )
+ )
+
addQueryParams(queryParams)
return retrofitManager.accessManagerService
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/access/GrantTokenEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/access/GrantTokenEndpoint.kt
index 19dc000e72..8fb9d4018b 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/access/GrantTokenEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/access/GrantTokenEndpoint.kt
@@ -4,6 +4,8 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.access.GrantToken
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.access_manager.v3.ChannelGrant
import com.pubnub.api.models.consumer.access_manager.v3.ChannelGroupGrant
import com.pubnub.api.models.consumer.access_manager.v3.PNGrantTokenResult
@@ -12,6 +14,8 @@ import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.api.v2.PNConfiguration.Companion.isValid
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.access_manager.v3.GrantTokenRequestBody
import com.pubnub.internal.models.server.access_manager.v3.GrantTokenResponse
import retrofit2.Call
@@ -26,6 +30,8 @@ class GrantTokenEndpoint(
private val channelGroups: List,
private val uuids: List,
) : EndpointCore(pubnub), GrantToken {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun getAffectedChannels(): List = channels.map { it.id }
override fun getAffectedChannelGroups(): List = channelGroups.map { it.id }
@@ -46,6 +52,25 @@ class GrantTokenEndpoint(
}
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "ttl" to ttl,
+ "meta" to (meta ?: ""),
+ "authorizedUUID" to (authorizedUUID ?: ""),
+ "channels" to channels.map {
+ mapOf("id" to it.id, "read" to it.read, "write" to it.write, "manage" to it.manage, "delete" to it.delete, "get" to it.get, "update" to it.update, "join" to it.join)
+ },
+ "channelGroups" to channelGroups.map { mapOf("id" to it.id, "read" to it.read, "write" to it.write, "manage" to it.manage) },
+ "uuids" to uuids.map { mapOf("id" to it.id, "get" to it.get, "update" to it.update, "delete" to it.delete) },
+ "queryParams" to queryParams
+ )
+ ),
+ details = "GrantToken API call",
+ )
+ )
+
val requestBody: GrantTokenRequestBody =
GrantTokenRequestBody.of(
ttl = ttl,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/access/RevokeTokenEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/access/RevokeTokenEndpoint.kt
index 789e8f0175..9bf0f1cbc1 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/access/RevokeTokenEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/access/RevokeTokenEndpoint.kt
@@ -4,10 +4,14 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.access.RevokeToken
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.api.v2.PNConfiguration.Companion.isValid
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.access_manager.v3.RevokeTokenResponse
import retrofit2.Call
import retrofit2.Response
@@ -17,6 +21,8 @@ class RevokeTokenEndpoint(
pubnub: PubNubImpl,
private val token: String,
) : EndpointCore(pubnub), RevokeToken {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun validateParams() {
super.validateParams()
if (!pubnub.configuration.secretKey.isValid()) {
@@ -28,6 +34,18 @@ class RevokeTokenEndpoint(
}
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "token" to token,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "RevokeToken API call",
+ )
+ )
+
return retrofitManager
.accessManagerService
.revokeToken(configuration.subscribeKey, repairEncoding(token), queryParams)
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/AddChannelChannelGroupEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/AddChannelChannelGroupEndpoint.kt
index 18550b48de..81142a359d 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/AddChannelChannelGroupEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/AddChannelChannelGroupEndpoint.kt
@@ -4,10 +4,14 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.channel_groups.AddChannelChannelGroup
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.channel_group.PNChannelGroupsAddChannelResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.toCsv
import retrofit2.Call
import retrofit2.Response
@@ -20,6 +24,8 @@ class AddChannelChannelGroupEndpoint internal constructor(
override val channelGroup: String,
override val channels: List,
) : EndpointCore(pubnub), AddChannelChannelGroup {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun getAffectedChannels() = channels
override fun getAffectedChannelGroups() = listOf(channelGroup)
@@ -35,6 +41,19 @@ class AddChannelChannelGroupEndpoint internal constructor(
}
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channelGroup" to channelGroup,
+ "channels" to channels,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "AddChannelChannelGroup API call",
+ )
+ )
+
addQueryParams(queryParams)
return retrofitManager.channelGroupService
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/AllChannelsChannelGroupEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/AllChannelsChannelGroupEndpoint.kt
index 7c6c074cfb..eba83bb319 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/AllChannelsChannelGroupEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/AllChannelsChannelGroupEndpoint.kt
@@ -4,10 +4,14 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.channel_groups.AllChannelsChannelGroup
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.channel_group.PNChannelGroupsAllChannelsResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.Envelope
import retrofit2.Call
import retrofit2.Response
@@ -20,6 +24,8 @@ class AllChannelsChannelGroupEndpoint internal constructor(
override val channelGroup: String,
) : EndpointCore>, PNChannelGroupsAllChannelsResult>(pubnub),
AllChannelsChannelGroup {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun getAffectedChannelGroups() = listOf(channelGroup)
override fun validateParams() {
@@ -30,6 +36,18 @@ class AllChannelsChannelGroupEndpoint internal constructor(
}
override fun doWork(queryParams: HashMap): Call>> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channelGroup" to channelGroup,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "AllChannelsChannelGroup API call",
+ )
+ )
+
return retrofitManager.channelGroupService
.allChannelsChannelGroup(
configuration.subscribeKey,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/DeleteChannelGroupEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/DeleteChannelGroupEndpoint.kt
index f06ba172d4..d6a79fff8f 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/DeleteChannelGroupEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/DeleteChannelGroupEndpoint.kt
@@ -4,10 +4,14 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.channel_groups.DeleteChannelGroup
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.channel_group.PNChannelGroupsDeleteGroupResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import retrofit2.Call
import retrofit2.Response
@@ -18,6 +22,8 @@ class DeleteChannelGroupEndpoint internal constructor(
pubnub: PubNubImpl,
override val channelGroup: String,
) : EndpointCore(pubnub), DeleteChannelGroup {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun validateParams() {
super.validateParams()
if (channelGroup.isBlank()) {
@@ -28,6 +34,18 @@ class DeleteChannelGroupEndpoint internal constructor(
override fun getAffectedChannelGroups() = listOf(channelGroup)
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channelGroup" to channelGroup,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "DeleteChannelGroup API call",
+ )
+ )
+
return retrofitManager.channelGroupService
.deleteChannelGroup(
configuration.subscribeKey,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/ListAllChannelGroupEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/ListAllChannelGroupEndpoint.kt
index d9bf4ec709..591db078d6 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/ListAllChannelGroupEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/ListAllChannelGroupEndpoint.kt
@@ -2,10 +2,14 @@ package com.pubnub.internal.endpoints.channel_groups
import com.pubnub.api.endpoints.channel_groups.ListAllChannelGroup
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.channel_group.PNChannelGroupsListAllResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.Envelope
import retrofit2.Call
import retrofit2.Response
@@ -16,7 +20,20 @@ import retrofit2.Response
class ListAllChannelGroupEndpoint internal constructor(pubnub: PubNubImpl) :
EndpointCore>, PNChannelGroupsListAllResult>(pubnub),
ListAllChannelGroup {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call>> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "queryParams" to queryParams
+ )
+ ),
+ details = "ListAllChannelGroup API call",
+ )
+ )
+
return retrofitManager.channelGroupService
.listAllChannelGroup(
configuration.subscribeKey,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/RemoveChannelChannelGroupEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/RemoveChannelChannelGroupEndpoint.kt
index 2e9bda8b04..fa8b2af8a9 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/RemoveChannelChannelGroupEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/channel_groups/RemoveChannelChannelGroupEndpoint.kt
@@ -4,10 +4,14 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.channel_groups.RemoveChannelChannelGroup
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.channel_group.PNChannelGroupsRemoveChannelResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.toCsv
import retrofit2.Call
import retrofit2.Response
@@ -20,6 +24,8 @@ class RemoveChannelChannelGroupEndpoint internal constructor(
override val channelGroup: String,
override val channels: List,
) : EndpointCore(pubnub), RemoveChannelChannelGroup {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun getAffectedChannels() = channels
override fun getAffectedChannelGroups() = listOf(channelGroup)
@@ -35,6 +41,19 @@ class RemoveChannelChannelGroupEndpoint internal constructor(
}
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channelGroup" to channelGroup,
+ "channels" to channels,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "RemoveChannelChannelGroup API call",
+ )
+ )
+
addQueryParams(queryParams)
return retrofitManager.channelGroupService
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/DeleteFileEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/DeleteFileEndpoint.kt
index 282f3d5c6f..5fc84d6ba1 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/DeleteFileEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/DeleteFileEndpoint.kt
@@ -4,10 +4,14 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.files.DeleteFile
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.files.PNDeleteFileResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import retrofit2.Call
import retrofit2.Response
@@ -20,6 +24,8 @@ class DeleteFileEndpoint(
private val fileId: String,
pubNub: PubNubImpl,
) : EndpointCore(pubNub), DeleteFile {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
@Throws(PubNubException::class)
override fun validateParams() {
if (channel.isEmpty()) {
@@ -28,14 +34,29 @@ class DeleteFileEndpoint(
}
@Throws(PubNubException::class)
- override fun doWork(queryParams: HashMap): Call =
- retrofitManager.filesService.deleteFile(
+ override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "fileName" to fileName,
+ "fileId" to fileId,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "DeleteFile API call",
+ )
+ )
+
+ return retrofitManager.filesService.deleteFile(
configuration.subscribeKey,
channel,
fileId,
fileName,
queryParams,
)
+ }
@Throws(PubNubException::class)
override fun createResponse(input: Response): PNDeleteFileResult =
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/DownloadFileEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/DownloadFileEndpoint.kt
index 1e51c78e4d..1d7d90b3a0 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/DownloadFileEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/DownloadFileEndpoint.kt
@@ -5,10 +5,14 @@ import com.pubnub.api.PubNubException
import com.pubnub.api.crypto.CryptoModule
import com.pubnub.api.endpoints.files.DownloadFile
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.files.PNDownloadFileResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Response
@@ -23,6 +27,8 @@ class DownloadFileEndpoint(
private val cryptoModule: CryptoModule? = null,
pubNub: PubNubImpl,
) : EndpointCore(pubNub), DownloadFile {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
@Throws(PubNubException::class)
override fun validateParams() {
if (channel.isEmpty()) {
@@ -31,14 +37,30 @@ class DownloadFileEndpoint(
}
@Throws(PubNubException::class)
- override fun doWork(queryParams: HashMap): Call =
- retrofitManager.filesService.downloadFile(
+ override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "fileName" to fileName,
+ "fileId" to fileId,
+ "cryptoModule" to (cryptoModule != null).toString(),
+ "queryParams" to queryParams
+ )
+ ),
+ details = "DownloadFile API call",
+ )
+ )
+
+ return retrofitManager.filesService.downloadFile(
configuration.subscribeKey,
channel,
fileId,
fileName,
queryParams,
)
+ }
@Throws(PubNubException::class)
override fun createResponse(input: Response): PNDownloadFileResult {
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/GenerateUploadUrlEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/GenerateUploadUrlEndpoint.kt
index 2d2056af19..a7dbab028c 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/GenerateUploadUrlEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/GenerateUploadUrlEndpoint.kt
@@ -4,9 +4,13 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.remoteaction.ExtendedRemoteAction
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.files.FileUploadRequestDetails
import com.pubnub.internal.models.server.files.FormField
import com.pubnub.internal.models.server.files.GenerateUploadUrlPayload
@@ -19,6 +23,8 @@ internal class GenerateUploadUrlEndpoint(
private val fileName: String,
pubNub: PubNubImpl,
) : EndpointCore(pubNub) {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
@Throws(PubNubException::class)
override fun validateParams() {
if (channel.isEmpty()) {
@@ -53,6 +59,19 @@ internal class GenerateUploadUrlEndpoint(
}
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "fileName" to fileName,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "GenerateUploadUrl API call",
+ )
+ )
+
return retrofitManager.filesService.generateUploadUrl(
configuration.subscribeKey,
channel,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/GetFileUrlEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/GetFileUrlEndpoint.kt
index 171ebc0425..86591058c5 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/GetFileUrlEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/GetFileUrlEndpoint.kt
@@ -4,12 +4,16 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.files.GetFileUrl
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.files.PNFileUrlResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.api.v2.callbacks.Result
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.PubNubUtil
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Response
@@ -26,6 +30,7 @@ class GetFileUrlEndpoint(
private val fileId: String,
pubNub: PubNubImpl,
) : EndpointCore(pubNub), GetFileUrl {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
private lateinit var cachedCallback: Consumer>
private val executorService: ExecutorService = retrofitManager.getTransactionClientExecutorService() ?: Executors.newSingleThreadExecutor()
@@ -42,6 +47,19 @@ class GetFileUrlEndpoint(
// properly constructed url the code creates a request which isn't executed
@Throws(PubNubException::class)
override fun sync(): PNFileUrlResult {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "fileName" to fileName,
+ "fileId" to fileId
+ )
+ ),
+ details = "GetFileUrl API call",
+ )
+ )
+
return try {
val baseParams: Map = createBaseParams()
val call: Call =
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/ListFilesEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/ListFilesEndpoint.kt
index e5e9868c82..9b87579f57 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/ListFilesEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/ListFilesEndpoint.kt
@@ -4,11 +4,15 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.files.ListFiles
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.files.PNListFilesResult
import com.pubnub.api.models.consumer.objects.PNPage
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.files.ListFilesResult
import retrofit2.Call
import retrofit2.Response
@@ -22,6 +26,8 @@ class ListFilesEndpoint(
private val next: PNPage.PNNext? = null,
pubNub: PubNubImpl,
) : EndpointCore(pubNub), ListFiles {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
@Throws(PubNubException::class)
override fun validateParams() {
if (channel.isEmpty()) {
@@ -41,6 +47,20 @@ class ListFilesEndpoint(
@Throws(PubNubException::class)
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "limit" to (limit ?: DEFAULT_LIMIT),
+ "next" to (next?.pageHash ?: ""),
+ "queryParams" to queryParams
+ )
+ ),
+ details = "ListFiles API call",
+ )
+ )
+
queryParams[LIMIT_QUERY_PARAM] = (limit ?: DEFAULT_LIMIT).toString()
if (next != null) {
queryParams[NEXT_PAGE_QUERY_PARAM] = next.pageHash
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/PublishFileMessageEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/PublishFileMessageEndpoint.kt
index 46d30e7645..2bad1c64ce 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/PublishFileMessageEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/PublishFileMessageEndpoint.kt
@@ -5,6 +5,8 @@ import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.files.PublishFileMessage
import com.pubnub.api.endpoints.remoteaction.ExtendedRemoteAction
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.files.PNBaseFile
import com.pubnub.api.models.consumer.files.PNPublishFileMessageResult
import com.pubnub.api.retry.RetryableEndpointGroup
@@ -14,6 +16,8 @@ import com.pubnub.internal.crypto.encryptString
import com.pubnub.internal.endpoints.pubsub.PublishEndpoint.Companion.CUSTOM_MESSAGE_TYPE_QUERY_PARAM
import com.pubnub.internal.extension.numericString
import com.pubnub.internal.extension.quoted
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.files.FileUploadNotification
import retrofit2.Call
import retrofit2.Response
@@ -32,6 +36,7 @@ open class PublishFileMessageEndpoint(
private val customMessageType: String? = null,
pubNub: PubNubImpl,
) : EndpointCore, PNPublishFileMessageResult>(pubNub), PublishFileMessage {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
private val pnFile = PNBaseFile(fileId, fileName)
@Throws(PubNubException::class)
@@ -43,8 +48,27 @@ open class PublishFileMessageEndpoint(
@Throws(PubNubException::class)
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "fileName" to pnFile.name,
+ "fileId" to pnFile.id,
+ "message" to (message ?: ""),
+ "meta" to (meta ?: ""),
+ "ttl" to (ttl ?: 0),
+ "shouldStore" to (shouldStore ?: true),
+ "customMessageType" to (customMessageType ?: ""),
+ "queryParams" to queryParams
+ )
+ ),
+ details = "PublishFileMessage API call",
+ )
+ )
+
val stringifiedMessage: String = pubnub.mapper.toJson(FileUploadNotification(message, pnFile))
- val messageAsString = configuration.cryptoModule?.encryptString(stringifiedMessage)?.quoted() ?: stringifiedMessage
+ val messageAsString = pubnub.cryptoModuleWithLogConfig?.encryptString(stringifiedMessage)?.quoted() ?: stringifiedMessage
meta?.let {
val stringifiedMeta: String = pubnub.mapper.toJson(it)
queryParams["meta"] = stringifiedMeta
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/SendFileEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/SendFileEndpoint.kt
index b6e0c0e21d..d0e7059046 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/SendFileEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/SendFileEndpoint.kt
@@ -92,14 +92,14 @@ class SendFileEndpoint internal constructor(
cryptoModule?.encryptStream(InputStreamSeparator(inputStream))?.use {
it.readBytes()
} ?: inputStream.readBytes()
- return ComposableRemoteAction.firstDo(generateUploadUrlFactory.create(channel, fileName)) // generateUrl
+ return ComposableRemoteAction.firstDo(generateUploadUrlFactory.create(channel, fileName)) // 1. generateUrl
.then { res ->
result.set(res)
- sendFileToS3Factory.create(fileName, content, res) // upload to s3
+ sendFileToS3Factory.create(fileName, content, res) // 2. upload to s3
}.checkpoint().then {
val details = result.get()
RetryingRemoteAction.autoRetry(
- publishFileMessageFactory.create(
+ publishFileMessageFactory.create( // 3. PublishFileMessage
channel = channel,
fileName = details.data.name,
fileId = details.data.id,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/UploadFileEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/UploadFileEndpoint.kt
index b773734859..e14301eed3 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/UploadFileEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/files/UploadFileEndpoint.kt
@@ -4,8 +4,12 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.remoteaction.ExtendedRemoteAction
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.v2.callbacks.Result
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
import com.pubnub.internal.models.server.files.FileUploadRequestDetails
import com.pubnub.internal.models.server.files.FormField
import com.pubnub.internal.services.S3Service
@@ -13,7 +17,6 @@ import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.toRequestBody
-import org.slf4j.LoggerFactory
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
@@ -32,8 +35,10 @@ internal class UploadFileEndpoint(
private val key: FormField,
private val formParams: List,
private val baseUrl: String,
+ private val logConfig: LogConfig
) : ExtendedRemoteAction {
private var call: Call? = null
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
@Throws(PubNubException::class)
private fun prepareCall(): Call {
@@ -58,7 +63,11 @@ internal class UploadFileEndpoint(
try {
contentType.toMediaType()
} catch (t: Throwable) {
- log.warn("Content-Type: $contentType was not recognized by MediaType.get", t)
+ log.warn(
+ LogMessage(
+ message = LogMessageContent.Text("Content-Type: $contentType was not recognized by MediaType.get: ${t.message}"),
+ )
+ )
APPLICATION_OCTET_STREAM
}
}
@@ -182,6 +191,7 @@ internal class UploadFileEndpoint(
fileUploadRequestDetails.keyFormField,
fileUploadRequestDetails.formFields,
fileUploadRequestDetails.url,
+ pubNub.logConfig
)
}
}
@@ -190,7 +200,6 @@ internal class UploadFileEndpoint(
private val APPLICATION_OCTET_STREAM = "application/octet-stream".toMediaType()
private const val CONTENT_TYPE_HEADER = "Content-Type"
private const val FILE_PART_MULTIPART = "file"
- private val log = LoggerFactory.getLogger(UploadFileEndpoint::class.java)
private fun addFormParamsWithKeyFirst(
keyValue: FormField,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/message_actions/AddMessageActionEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/message_actions/AddMessageActionEndpoint.kt
index fec91da582..e61adb4072 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/message_actions/AddMessageActionEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/message_actions/AddMessageActionEndpoint.kt
@@ -5,11 +5,15 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.message_actions.AddMessageAction
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.message_actions.PNAddMessageActionResult
import com.pubnub.api.models.consumer.message_actions.PNMessageAction
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.objects_api.EntityEnvelope
import retrofit2.Call
import retrofit2.Response
@@ -23,6 +27,8 @@ class AddMessageActionEndpoint internal constructor(
override val channel: String,
override val messageAction: PNMessageAction,
) : EndpointCore, PNAddMessageActionResult>(pubnub), AddMessageAction {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun validateParams() {
super.validateParams()
if (channel.isBlank()) {
@@ -39,6 +45,21 @@ class AddMessageActionEndpoint internal constructor(
override fun getAffectedChannels() = listOf(channel)
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "messageActionType" to messageAction.type,
+ "messageActionValue" to messageAction.value,
+ "messageTimetoken" to messageAction.messageTimetoken,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "AddMessageAction API call",
+ )
+ )
+
val body =
JsonObject().apply {
addProperty("type", messageAction.type)
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/message_actions/GetMessageActionsEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/message_actions/GetMessageActionsEndpoint.kt
index 07b3455acd..7140160ab4 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/message_actions/GetMessageActionsEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/message_actions/GetMessageActionsEndpoint.kt
@@ -4,11 +4,15 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.message_actions.GetMessageActions
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.PNBoundedPage
import com.pubnub.api.models.consumer.message_actions.PNGetMessageActionsResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import retrofit2.Call
import retrofit2.Response
import java.util.Locale
@@ -21,6 +25,8 @@ class GetMessageActionsEndpoint internal constructor(
override val channel: String,
override val page: PNBoundedPage,
) : EndpointCore(pubnub), GetMessageActions {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun validateParams() {
super.validateParams()
if (channel.isBlank()) {
@@ -31,6 +37,21 @@ class GetMessageActionsEndpoint internal constructor(
override fun getAffectedChannels() = listOf(channel)
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "pageStart" to (page.start ?: ""),
+ "pageEnd" to (page.end ?: ""),
+ "pageLimit" to (page.limit ?: 100),
+ "queryParams" to queryParams
+ )
+ ),
+ details = "GetMessageActions API call",
+ )
+ )
+
addQueryParams(queryParams)
return retrofitManager.messageActionService
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/message_actions/RemoveMessageActionEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/message_actions/RemoveMessageActionEndpoint.kt
index 82126bb310..589876afe7 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/message_actions/RemoveMessageActionEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/message_actions/RemoveMessageActionEndpoint.kt
@@ -4,10 +4,14 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.message_actions.RemoveMessageAction
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.message_actions.PNRemoveMessageActionResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import retrofit2.Call
import retrofit2.Response
import java.util.Locale
@@ -21,6 +25,8 @@ class RemoveMessageActionEndpoint internal constructor(
override val messageTimetoken: Long,
override val actionTimetoken: Long,
) : EndpointCore(pubnub), RemoveMessageAction {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun validateParams() {
super.validateParams()
if (channel.isBlank()) {
@@ -31,6 +37,20 @@ class RemoveMessageActionEndpoint internal constructor(
override fun getAffectedChannels() = listOf(channel)
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "messageTimetoken" to messageTimetoken,
+ "actionTimetoken" to actionTimetoken,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "RemoveMessageAction API call",
+ )
+ )
+
return retrofitManager.messageActionService
.deleteMessageAction(
subKey = configuration.subscribeKey,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/GetAllChannelMetadataEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/GetAllChannelMetadataEndpoint.kt
index 064635fe46..3ff7db1a0f 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/GetAllChannelMetadataEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/GetAllChannelMetadataEndpoint.kt
@@ -2,6 +2,8 @@ package com.pubnub.internal.endpoints.objects.channel
import com.pubnub.api.endpoints.objects.channel.GetAllChannelMetadata
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.objects.PNPage
import com.pubnub.api.models.consumer.objects.channel.PNChannelMetadata
import com.pubnub.api.models.consumer.objects.channel.PNChannelMetadataArrayResult
@@ -10,6 +12,8 @@ import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.endpoints.objects.internal.CollectionQueryParameters
import com.pubnub.internal.endpoints.objects.internal.IncludeQueryParam
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.objects_api.EntityArrayEnvelope
import retrofit2.Call
import retrofit2.Response
@@ -23,7 +27,19 @@ class GetAllChannelMetadataEndpoint internal constructor(
private val includeQueryParam: IncludeQueryParam,
) : EndpointCore, PNChannelMetadataArrayResult>(pubnub),
GetAllChannelMetadata {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "queryParams" to queryParams
+ )
+ ),
+ details = "GetAllChannelMetadata API call",
+ )
+ )
val params =
queryParams + collectionQueryParameters.createCollectionQueryParams() + includeQueryParam.createIncludeQueryParams()
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/GetChannelMetadataEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/GetChannelMetadataEndpoint.kt
index e0b7ae22de..945a3ddf93 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/GetChannelMetadataEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/GetChannelMetadataEndpoint.kt
@@ -2,12 +2,16 @@ package com.pubnub.internal.endpoints.objects.channel
import com.pubnub.api.endpoints.objects.channel.GetChannelMetadata
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.objects.channel.PNChannelMetadata
import com.pubnub.api.models.consumer.objects.channel.PNChannelMetadataResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.endpoints.objects.internal.IncludeQueryParam
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.objects_api.EntityEnvelope
import retrofit2.Call
import retrofit2.Response
@@ -20,7 +24,20 @@ class GetChannelMetadataEndpoint internal constructor(
private val channel: String,
private val includeQueryParam: IncludeQueryParam,
) : EndpointCore, PNChannelMetadataResult>(pubnub), GetChannelMetadata {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "GetChannelMetadata API call",
+ )
+ )
val params = queryParams + includeQueryParam.createIncludeQueryParams()
return retrofitManager.objectsService.getChannelMetadata(
subKey = configuration.subscribeKey,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/RemoveChannelMetadataEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/RemoveChannelMetadataEndpoint.kt
index 8e0c311bc0..61691660f8 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/RemoveChannelMetadataEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/RemoveChannelMetadataEndpoint.kt
@@ -2,10 +2,14 @@ package com.pubnub.internal.endpoints.objects.channel
import com.pubnub.api.endpoints.objects.channel.RemoveChannelMetadata
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.objects.PNRemoveMetadataResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.objects_api.EntityEnvelope
import retrofit2.Call
import retrofit2.Response
@@ -14,7 +18,20 @@ class RemoveChannelMetadataEndpoint(
pubnub: PubNubImpl,
private val channel: String,
) : EndpointCore, PNRemoveMetadataResult>(pubnub), RemoveChannelMetadata {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "RemoveChannelMetadata API call",
+ )
+ )
return retrofitManager.objectsService.deleteChannelMetadata(
subKey = configuration.subscribeKey,
channel = channel,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/SetChannelMetadataEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/SetChannelMetadataEndpoint.kt
index a89ac1a6cc..820faacc82 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/SetChannelMetadataEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/channel/SetChannelMetadataEndpoint.kt
@@ -2,12 +2,16 @@ package com.pubnub.internal.endpoints.objects.channel
import com.pubnub.api.endpoints.objects.channel.SetChannelMetadata
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.objects.channel.PNChannelMetadata
import com.pubnub.api.models.consumer.objects.channel.PNChannelMetadataResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.endpoints.objects.internal.IncludeQueryParam
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.objects_api.ChannelMetadataInput
import com.pubnub.internal.models.server.objects_api.EntityEnvelope
import retrofit2.Call
@@ -28,7 +32,28 @@ class SetChannelMetadataEndpoint internal constructor(
private val ifMatchesEtag: String?,
) : EndpointCore, PNChannelMetadataResult>(pubnub),
SetChannelMetadata {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "name" to (name ?: ""),
+ "description" to (description ?: ""),
+ "custom" to (custom ?: ""),
+ "type" to (type ?: ""),
+ "status" to (status ?: ""),
+ "ifMatchesEtag" to (ifMatchesEtag ?: ""),
+ "includeQueryParam" to includeQueryParam,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "SetChannelMetadata API call",
+ )
+ )
+
val params = queryParams + includeQueryParam.createIncludeQueryParams()
return retrofitManager.objectsService.setChannelMetadata(
subKey = configuration.subscribeKey,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/member/GetChannelMembersEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/member/GetChannelMembersEndpoint.kt
index 611bedbce2..4d7483d2f0 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/member/GetChannelMembersEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/member/GetChannelMembersEndpoint.kt
@@ -2,6 +2,8 @@ package com.pubnub.internal.endpoints.objects.member
import com.pubnub.api.endpoints.objects.member.GetChannelMembers
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.objects.member.PNMember
import com.pubnub.api.models.consumer.objects.member.PNMemberArrayResult
import com.pubnub.api.retry.RetryableEndpointGroup
@@ -10,6 +12,8 @@ import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.endpoints.objects.internal.CollectionQueryParameters
import com.pubnub.internal.endpoints.objects.internal.IncludeQueryParam
import com.pubnub.internal.extension.toPNMemberArrayResult
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.objects_api.EntityArrayEnvelope
import retrofit2.Call
import retrofit2.Response
@@ -23,7 +27,20 @@ class GetChannelMembersEndpoint internal constructor(
private val collectionQueryParameters: CollectionQueryParameters,
private val includeQueryParam: IncludeQueryParam,
) : EndpointCore, PNMemberArrayResult>(pubnub), GetChannelMembers {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "GetChannelMembers API call",
+ )
+ )
val params =
queryParams + collectionQueryParameters.createCollectionQueryParams() + includeQueryParam.createIncludeQueryParams()
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/member/ManageChannelMembersEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/member/ManageChannelMembersEndpoint.kt
index 0d26a331b3..048de5f3d6 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/member/ManageChannelMembersEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/member/ManageChannelMembersEndpoint.kt
@@ -2,6 +2,8 @@ package com.pubnub.internal.endpoints.objects.member
import com.pubnub.api.endpoints.objects.member.ManageChannelMembers
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.objects.member.MemberInput
import com.pubnub.api.models.consumer.objects.member.PNMember
import com.pubnub.api.models.consumer.objects.member.PNMemberArrayResult
@@ -11,6 +13,8 @@ import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.endpoints.objects.internal.CollectionQueryParameters
import com.pubnub.internal.endpoints.objects.internal.IncludeQueryParam
import com.pubnub.internal.extension.toPNMemberArrayResult
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.objects_api.ChangeMemberInput
import com.pubnub.internal.models.server.objects_api.EntityArrayEnvelope
import com.pubnub.internal.models.server.objects_api.ServerMemberInput
@@ -29,7 +33,22 @@ class ManageChannelMembersEndpoint(
private val collectionQueryParameters: CollectionQueryParameters,
private val includeQueryParam: IncludeQueryParam,
) : EndpointCore, PNMemberArrayResult>(pubnub), ManageChannelMembers {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "userToSet" to userToSet,
+ "userIdsRemove" to userIdsRemove,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "ManageChannelMembers API call",
+ )
+ )
val params =
queryParams + collectionQueryParameters.createCollectionQueryParams() + includeQueryParam.createIncludeQueryParams()
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/membership/GetMembershipsEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/membership/GetMembershipsEndpoint.kt
index a4e9b33ca5..83f8ee42ed 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/membership/GetMembershipsEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/membership/GetMembershipsEndpoint.kt
@@ -2,6 +2,8 @@ package com.pubnub.internal.endpoints.objects.membership
import com.pubnub.api.endpoints.objects.membership.GetMemberships
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.objects.membership.PNChannelMembership
import com.pubnub.api.models.consumer.objects.membership.PNChannelMembershipArrayResult
import com.pubnub.api.retry.RetryableEndpointGroup
@@ -10,6 +12,8 @@ import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.endpoints.objects.internal.CollectionQueryParameters
import com.pubnub.internal.endpoints.objects.internal.IncludeQueryParam
import com.pubnub.internal.extension.toPNChannelMembershipArrayResult
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.objects_api.EntityArrayEnvelope
import retrofit2.Call
import retrofit2.Response
@@ -24,7 +28,20 @@ class GetMembershipsEndpoint internal constructor(
private val includeQueryParam: IncludeQueryParam,
) : EndpointCore, PNChannelMembershipArrayResult>(pubnub),
GetMemberships {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "uuid" to uuid,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "GetMemberships API call",
+ )
+ )
val params =
queryParams + collectionQueryParameters.createCollectionQueryParams() + includeQueryParam.createIncludeQueryParams()
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/membership/ManageMembershipsEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/membership/ManageMembershipsEndpoint.kt
index 90cf97a579..76ebb1c3d5 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/membership/ManageMembershipsEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/membership/ManageMembershipsEndpoint.kt
@@ -2,6 +2,8 @@ package com.pubnub.internal.endpoints.objects.membership
import com.pubnub.api.endpoints.objects.membership.ManageMemberships
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.objects.membership.ChannelMembershipInput
import com.pubnub.api.models.consumer.objects.membership.PNChannelMembership
import com.pubnub.api.models.consumer.objects.membership.PNChannelMembershipArrayResult
@@ -11,6 +13,8 @@ import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.endpoints.objects.internal.CollectionQueryParameters
import com.pubnub.internal.endpoints.objects.internal.IncludeQueryParam
import com.pubnub.internal.extension.toPNChannelMembershipArrayResult
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.objects_api.ChangeMembershipInput
import com.pubnub.internal.models.server.objects_api.ChannelId
import com.pubnub.internal.models.server.objects_api.EntityArrayEnvelope
@@ -30,7 +34,22 @@ class ManageMembershipsEndpoint internal constructor(
private val includeQueryParam: IncludeQueryParam,
) : EndpointCore, PNChannelMembershipArrayResult>(pubnub),
ManageMemberships {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "uuid" to uuid,
+ "channelsToSet" to channelsToSet,
+ "channelsToRemove" to channelsToRemove,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "ManageMemberships API call",
+ )
+ )
val params =
queryParams + collectionQueryParameters.createCollectionQueryParams() +
includeQueryParam.createIncludeQueryParams()
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/GetAllUUIDMetadataEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/GetAllUUIDMetadataEndpoint.kt
index 33a7159959..b5fa964de8 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/GetAllUUIDMetadataEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/GetAllUUIDMetadataEndpoint.kt
@@ -2,6 +2,8 @@ package com.pubnub.internal.endpoints.objects.uuid
import com.pubnub.api.endpoints.objects.uuid.GetAllUUIDMetadata
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.objects.PNPage
import com.pubnub.api.models.consumer.objects.uuid.PNUUIDMetadata
import com.pubnub.api.models.consumer.objects.uuid.PNUUIDMetadataArrayResult
@@ -10,6 +12,8 @@ import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.endpoints.objects.internal.CollectionQueryParameters
import com.pubnub.internal.endpoints.objects.internal.IncludeQueryParam
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.objects_api.EntityArrayEnvelope
import retrofit2.Call
import retrofit2.Response
@@ -23,7 +27,19 @@ class GetAllUUIDMetadataEndpoint internal constructor(
private val withInclude: IncludeQueryParam,
) : EndpointCore, PNUUIDMetadataArrayResult>(pubnub),
GetAllUUIDMetadata {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "queryParams" to queryParams
+ )
+ ),
+ details = "GetAllUUIDMetadata API call",
+ )
+ )
val params =
queryParams + collectionQueryParameters.createCollectionQueryParams() + withInclude.createIncludeQueryParams()
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/GetUUIDMetadataEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/GetUUIDMetadataEndpoint.kt
index c72bf298b4..96686cd6ca 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/GetUUIDMetadataEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/GetUUIDMetadataEndpoint.kt
@@ -2,12 +2,16 @@ package com.pubnub.internal.endpoints.objects.uuid
import com.pubnub.api.endpoints.objects.uuid.GetUUIDMetadata
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.objects.uuid.PNUUIDMetadata
import com.pubnub.api.models.consumer.objects.uuid.PNUUIDMetadataResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.endpoints.objects.internal.IncludeQueryParam
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.objects_api.EntityEnvelope
import retrofit2.Call
import retrofit2.Response
@@ -20,7 +24,20 @@ class GetUUIDMetadataEndpoint internal constructor(
override val uuid: String,
private val includeQueryParam: IncludeQueryParam,
) : EndpointCore, PNUUIDMetadataResult>(pubnub), GetUUIDMetadata {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "uuid" to uuid,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "GetUUIDMetadata API call",
+ )
+ )
val params = queryParams + includeQueryParam.createIncludeQueryParams()
return retrofitManager.objectsService.getUUIDMetadata(
subKey = configuration.subscribeKey,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/RemoveUUIDMetadataEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/RemoveUUIDMetadataEndpoint.kt
index 45ef82e1cb..22cc4780e9 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/RemoveUUIDMetadataEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/RemoveUUIDMetadataEndpoint.kt
@@ -2,10 +2,14 @@ package com.pubnub.internal.endpoints.objects.uuid
import com.pubnub.api.endpoints.objects.uuid.RemoveUUIDMetadata
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.objects.PNRemoveMetadataResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.objects_api.EntityEnvelope
import retrofit2.Call
import retrofit2.Response
@@ -14,7 +18,20 @@ class RemoveUUIDMetadataEndpoint(
pubnub: PubNubImpl,
override val uuid: String? = null,
) : EndpointCore, PNRemoveMetadataResult>(pubnub), RemoveUUIDMetadata {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "uuid" to (uuid ?: configuration.userId.value),
+ "queryParams" to queryParams
+ )
+ ),
+ details = "RemoveUUIDMetadata API call",
+ )
+ )
return retrofitManager.objectsService.deleteUUIDMetadata(
subKey = configuration.subscribeKey,
uuid = uuid ?: configuration.userId.value,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/SetUUIDMetadataEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/SetUUIDMetadataEndpoint.kt
index 6d00fc11b5..f17e40b017 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/SetUUIDMetadataEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/objects/uuid/SetUUIDMetadataEndpoint.kt
@@ -2,12 +2,16 @@ package com.pubnub.internal.endpoints.objects.uuid
import com.pubnub.api.endpoints.objects.uuid.SetUUIDMetadata
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.objects.uuid.PNUUIDMetadata
import com.pubnub.api.models.consumer.objects.uuid.PNUUIDMetadataResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.endpoints.objects.internal.IncludeQueryParam
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.objects_api.EntityEnvelope
import com.pubnub.internal.models.server.objects_api.UUIDMetadataInput
import retrofit2.Call
@@ -29,7 +33,28 @@ class SetUUIDMetadataEndpoint internal constructor(
private val status: String?,
private val ifMatchesEtag: String?,
) : EndpointCore, PNUUIDMetadataResult>(pubnub), SetUUIDMetadata {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "uuid" to (uuid ?: configuration.userId.value),
+ "name" to (name ?: ""),
+ "externalId" to (externalId ?: ""),
+ "profileUrl" to (profileUrl ?: ""),
+ "email" to (email ?: ""),
+ "custom" to (custom ?: ""),
+ "type" to (type ?: ""),
+ "status" to (status ?: ""),
+ "ifMatchesEtag" to (ifMatchesEtag ?: ""),
+ "queryParams" to queryParams
+ )
+ ),
+ details = "SetUUIDMetadata API call",
+ )
+ )
val params = queryParams + withInclude.createIncludeQueryParams()
return retrofitManager.objectsService.setUUIDMetadata(
subKey = configuration.subscribeKey,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/GetStateEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/GetStateEndpoint.kt
index dbf2236826..2670840b3a 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/GetStateEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/GetStateEndpoint.kt
@@ -5,10 +5,14 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.presence.GetState
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.presence.PNGetStateResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.Envelope
import com.pubnub.internal.toCsv
import retrofit2.Call
@@ -23,6 +27,8 @@ class GetStateEndpoint internal constructor(
override val channelGroups: List,
override val uuid: String = pubnub.configuration.userId.value,
) : EndpointCore, PNGetStateResult>(pubnub), GetState {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun getAffectedChannels() = channels
override fun getAffectedChannelGroups() = channelGroups
@@ -35,6 +41,20 @@ class GetStateEndpoint internal constructor(
}
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channels" to channels,
+ "channelGroups" to channelGroups,
+ "uuid" to uuid,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "GetState API call",
+ )
+ )
+
addQueryParams(queryParams)
return retrofitManager.presenceService.getState(
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/HeartbeatEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/HeartbeatEndpoint.kt
index 5a851548ee..4cac9ab604 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/HeartbeatEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/HeartbeatEndpoint.kt
@@ -3,10 +3,14 @@ package com.pubnub.internal.endpoints.presence
import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.PubNubUtil
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import retrofit2.Call
import retrofit2.Response
@@ -16,6 +20,8 @@ class HeartbeatEndpoint internal constructor(
val channelGroups: List = listOf(),
val state: Any? = null,
) : EndpointCore(pubnub) {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun getAffectedChannels() = channels
override fun getAffectedChannelGroups() = channelGroups
@@ -33,6 +39,20 @@ class HeartbeatEndpoint internal constructor(
}
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channels" to channels,
+ "channelGroups" to channelGroups,
+ "state" to (state ?: ""),
+ "queryParams" to queryParams
+ )
+ ),
+ details = "Heartbeat API call",
+ )
+ )
+
addQueryParams(queryParams)
val channelsCsv =
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/HereNowEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/HereNowEndpoint.kt
index ba0d8ae308..4b4ef041d9 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/HereNowEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/HereNowEndpoint.kt
@@ -3,12 +3,16 @@ package com.pubnub.internal.endpoints.presence
import com.google.gson.JsonElement
import com.pubnub.api.endpoints.presence.HereNow
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.presence.PNHereNowChannelData
import com.pubnub.api.models.consumer.presence.PNHereNowOccupantData
import com.pubnub.api.models.consumer.presence.PNHereNowResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.Envelope
import com.pubnub.internal.toCsv
import retrofit2.Call
@@ -24,6 +28,8 @@ class HereNowEndpoint internal constructor(
override val includeState: Boolean = false,
override val includeUUIDs: Boolean = true,
) : EndpointCore, PNHereNowResult>(pubnub), HereNow {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
private fun isGlobalHereNow() = channels.isEmpty() && channelGroups.isEmpty()
override fun getAffectedChannels() = channels
@@ -31,6 +37,22 @@ class HereNowEndpoint internal constructor(
override fun getAffectedChannelGroups() = channelGroups
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channels" to channels,
+ "channelGroups" to channelGroups,
+ "includeState" to includeState,
+ "includeUUIDs" to includeUUIDs,
+ "isGlobalHereNow" to isGlobalHereNow(),
+ "queryParams" to queryParams
+ )
+ ),
+ details = "HereNow API call",
+ )
+ )
+
addQueryParams(queryParams)
return if (!isGlobalHereNow()) {
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/LeaveEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/LeaveEndpoint.kt
index 5b17411c74..5da6ee27d2 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/LeaveEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/LeaveEndpoint.kt
@@ -3,15 +3,21 @@ package com.pubnub.internal.endpoints.presence
import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.PubNubUtil
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.toCsv
import retrofit2.Call
import retrofit2.Response
class LeaveEndpoint internal constructor(pubnub: PubNubImpl) : EndpointCore(pubnub) {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
var channels = emptyList()
var channelGroups = emptyList()
@@ -32,6 +38,19 @@ class LeaveEndpoint internal constructor(pubnub: PubNubImpl) : EndpointCore): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channels" to channels,
+ "channelGroups" to channelGroups,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "Leave API call",
+ )
+ )
+
addQueryParams(queryParams)
return retrofitManager.presenceService.leave(
configuration.subscribeKey,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/SetStateEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/SetStateEndpoint.kt
index 063ef3cf2e..841ec0e025 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/SetStateEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/SetStateEndpoint.kt
@@ -6,10 +6,14 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.presence.SetState
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.presence.PNSetStateResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.Envelope
import com.pubnub.internal.presence.eventengine.data.PresenceData
import com.pubnub.internal.toCsv
@@ -27,6 +31,8 @@ class SetStateEndpoint internal constructor(
override val uuid: String = pubnub.configuration.userId.value,
private val presenceData: PresenceData,
) : EndpointCore, PNSetStateResult>(pubnub), SetState {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun getAffectedChannels() = channels
override fun getAffectedChannelGroups() = channelGroups
@@ -39,6 +45,21 @@ class SetStateEndpoint internal constructor(
}
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channels" to channels,
+ "channelGroups" to channelGroups,
+ "state" to state,
+ "uuid" to uuid,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "SetState API call",
+ )
+ )
+
if (uuid == pubnub.configuration.userId.value) {
val stateCopy = pubnub.mapper.fromJson(pubnub.mapper.toJson(state), JsonElement::class.java)
presenceData.channelStates.putAll(channels.associateWith { stateCopy })
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/WhereNowEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/WhereNowEndpoint.kt
index 2f5268949b..6545bb4de0 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/WhereNowEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/presence/WhereNowEndpoint.kt
@@ -2,10 +2,14 @@ package com.pubnub.internal.endpoints.presence
import com.pubnub.api.endpoints.presence.WhereNow
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.presence.PNWhereNowResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.Envelope
import com.pubnub.internal.models.server.presence.WhereNowPayload
import retrofit2.Call
@@ -18,7 +22,21 @@ class WhereNowEndpoint internal constructor(
pubnub: PubNubImpl,
override val uuid: String = pubnub.configuration.userId.value,
) : EndpointCore, PNWhereNowResult>(pubnub), WhereNow {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "uuid" to uuid,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "WhereNow API call",
+ )
+ )
+
return retrofitManager.presenceService.whereNow(
configuration.subscribeKey,
uuid,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/PublishEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/PublishEndpoint.kt
index f118e984fa..5d68aab1d7 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/PublishEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/PublishEndpoint.kt
@@ -4,6 +4,8 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.pubsub.Publish
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.PNPublishResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
@@ -12,6 +14,8 @@ import com.pubnub.internal.crypto.encryptString
import com.pubnub.internal.extension.numericString
import com.pubnub.internal.extension.quoted
import com.pubnub.internal.extension.valueString
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import retrofit2.Call
import retrofit2.Response
@@ -27,8 +31,10 @@ class PublishEndpoint internal constructor(
override val usePost: Boolean = false,
override val replicate: Boolean = true,
override val ttl: Int? = null,
- override val customMessageType: String? = null
+ override val customMessageType: String? = null,
) : EndpointCore, PNPublishResult>(pubnub), Publish {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
companion object {
internal const val CUSTOM_MESSAGE_TYPE_QUERY_PARAM = "custom_message_type"
}
@@ -43,6 +49,25 @@ class PublishEndpoint internal constructor(
override fun getAffectedChannels() = listOf(channel)
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "message" to message,
+ "channel" to channel,
+ "shouldStore" to (shouldStore ?: true),
+ "meta" to (meta ?: ""),
+ "queryParams" to queryParams,
+ "usePost" to usePost,
+ "ttl" to (ttl ?: 0),
+ "replicate" to replicate,
+ "customMessageType" to (customMessageType ?: "")
+ )
+ ),
+ details = "Publish API call"
+ )
+ )
+
addQueryParams(queryParams)
return if (usePost) {
@@ -58,7 +83,6 @@ class PublishEndpoint internal constructor(
} else {
// HTTP GET request
val stringifiedMessage = getParamMessage(message)
-
retrofitManager.publishService.publish(
configuration.publishKey,
configuration.subscribeKey,
@@ -100,10 +124,10 @@ class PublishEndpoint internal constructor(
// endregion
// region Message parsers
- private fun getBodyMessage(message: Any): Any = configuration.cryptoModule?.encryptString(toJson(message)) ?: message
+ private fun getBodyMessage(message: Any): Any = pubnub.cryptoModuleWithLogConfig?.encryptString(toJson(message)) ?: message
private fun getParamMessage(message: Any): String =
- configuration.cryptoModule?.encryptString(toJson(message))?.quoted() ?: toJson(message)
+ pubnub.cryptoModuleWithLogConfig?.encryptString(toJson(message))?.quoted() ?: toJson(message)
private fun toJson(message: Any): String = pubnub.mapper.toJson(message)
// endregion
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/SignalEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/SignalEndpoint.kt
index d65d5a6ec1..6823e57d97 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/SignalEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/SignalEndpoint.kt
@@ -4,10 +4,14 @@ import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.pubsub.Signal
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.PNPublishResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import retrofit2.Call
import retrofit2.Response
@@ -20,6 +24,8 @@ class SignalEndpoint internal constructor(
override val message: Any,
override val customMessageType: String? = null
) : EndpointCore, PNPublishResult>(pubnub), Signal {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
companion object {
private const val CUSTOM_MESSAGE_TYPE_QUERY_PARAM = "custom_message_type"
}
@@ -34,6 +40,20 @@ class SignalEndpoint internal constructor(
override fun getAffectedChannels() = listOf(channel)
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channel" to channel,
+ "message" to message,
+ "customMessageType" to (customMessageType ?: ""),
+ "queryParams" to queryParams
+ )
+ ),
+ details = "Signal API call",
+ )
+ )
+
customMessageType?.let { customMessageTypeNotNull ->
queryParams[CUSTOM_MESSAGE_TYPE_QUERY_PARAM] = customMessageTypeNotNull
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/SubscribeEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/SubscribeEndpoint.kt
index 9e779eccb6..c50d5176ad 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/SubscribeEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/SubscribeEndpoint.kt
@@ -3,16 +3,22 @@ package com.pubnub.internal.endpoints.pubsub
import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
import com.pubnub.api.enums.PNOperationType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.PubNubUtil
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.models.server.SubscribeEnvelope
import com.pubnub.internal.toCsv
import retrofit2.Call
import retrofit2.Response
class SubscribeEndpoint internal constructor(pubnub: PubNubImpl) : EndpointCore(pubnub) {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
var channels = emptyList()
var channelGroups = emptyList()
var timetoken: Long? = null
@@ -32,6 +38,23 @@ class SubscribeEndpoint internal constructor(pubnub: PubNubImpl) : EndpointCore<
override fun getAffectedChannelGroups() = channelGroups
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "channels" to channels,
+ "channelGroups" to channelGroups,
+ "timetoken" to (timetoken ?: 0L),
+ "region" to (region ?: ""),
+ "state" to (state ?: ""),
+ "filterExpression" to (filterExpression ?: ""),
+ "queryParams" to queryParams
+ )
+ ),
+ details = "Subscribe API call",
+ )
+ )
+
addQueryParams(queryParams)
return retrofitManager.subscribeService.subscribe(
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/AddChannelsToPushEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/AddChannelsToPushEndpoint.kt
index f5eb81182f..baf8d31551 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/AddChannelsToPushEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/AddChannelsToPushEndpoint.kt
@@ -6,10 +6,14 @@ import com.pubnub.api.endpoints.push.AddChannelsToPush
import com.pubnub.api.enums.PNOperationType
import com.pubnub.api.enums.PNPushEnvironment
import com.pubnub.api.enums.PNPushType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.push.PNPushAddChannelResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.toCsv
import retrofit2.Call
import retrofit2.Response
@@ -26,6 +30,8 @@ class AddChannelsToPushEndpoint internal constructor(
override val topic: String? = null,
override val environment: PNPushEnvironment = PNPushEnvironment.DEVELOPMENT,
) : EndpointCore(pubnub), AddChannelsToPush {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun getAffectedChannels() = channels
override fun validateParams() {
@@ -42,6 +48,22 @@ class AddChannelsToPushEndpoint internal constructor(
}
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "pushType" to pushType,
+ "channels" to channels,
+ "deviceId" to deviceId,
+ "topic" to (topic ?: ""),
+ "environment" to environment,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "AddChannelsToPush API call",
+ )
+ )
+
addQueryParams(queryParams)
return if (pushType != PNPushType.APNS2) {
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/ListPushProvisionsEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/ListPushProvisionsEndpoint.kt
index 9033f4279a..3f46e889b4 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/ListPushProvisionsEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/ListPushProvisionsEndpoint.kt
@@ -6,10 +6,14 @@ import com.pubnub.api.endpoints.push.ListPushProvisions
import com.pubnub.api.enums.PNOperationType
import com.pubnub.api.enums.PNPushEnvironment
import com.pubnub.api.enums.PNPushType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.push.PNPushListProvisionsResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import retrofit2.Call
import retrofit2.Response
import java.util.Locale
@@ -24,6 +28,8 @@ class ListPushProvisionsEndpoint internal constructor(
override val topic: String? = null,
override val environment: PNPushEnvironment = PNPushEnvironment.DEVELOPMENT,
) : EndpointCore, PNPushListProvisionsResult>(pubnub), ListPushProvisions {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun validateParams() {
super.validateParams()
if (deviceId.isBlank()) {
@@ -35,6 +41,21 @@ class ListPushProvisionsEndpoint internal constructor(
}
override fun doWork(queryParams: HashMap): Call> {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "pushType" to pushType,
+ "deviceId" to deviceId,
+ "topic" to (topic ?: ""),
+ "environment" to environment,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "ListPushProvisions API call",
+ )
+ )
+
addQueryParams(queryParams)
return if (pushType != PNPushType.APNS2) {
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/RemoveAllPushChannelsForDeviceEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/RemoveAllPushChannelsForDeviceEndpoint.kt
index 74bad7ee74..b15cd67b3d 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/RemoveAllPushChannelsForDeviceEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/RemoveAllPushChannelsForDeviceEndpoint.kt
@@ -6,10 +6,14 @@ import com.pubnub.api.endpoints.push.RemoveAllPushChannelsForDevice
import com.pubnub.api.enums.PNOperationType
import com.pubnub.api.enums.PNPushEnvironment
import com.pubnub.api.enums.PNPushType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.push.PNPushRemoveAllChannelsResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import retrofit2.Call
import retrofit2.Response
import java.util.Locale
@@ -24,6 +28,8 @@ class RemoveAllPushChannelsForDeviceEndpoint internal constructor(
override val environment: PNPushEnvironment = PNPushEnvironment.DEVELOPMENT,
override val topic: String? = null,
) : EndpointCore(pubnub), RemoveAllPushChannelsForDevice {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun validateParams() {
super.validateParams()
if (deviceId.isBlank()) {
@@ -35,6 +41,21 @@ class RemoveAllPushChannelsForDeviceEndpoint internal constructor(
}
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "pushType" to pushType,
+ "deviceId" to deviceId,
+ "environment" to environment,
+ "topic" to (topic ?: ""),
+ "queryParams" to queryParams
+ )
+ ),
+ details = "RemoveAllPushChannelsForDevice API call",
+ )
+ )
+
addQueryParams(queryParams)
return if (pushType != PNPushType.APNS2) {
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/RemoveChannelsFromPushEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/RemoveChannelsFromPushEndpoint.kt
index 5f4dbe477e..9fe3a0b56d 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/RemoveChannelsFromPushEndpoint.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/push/RemoveChannelsFromPushEndpoint.kt
@@ -6,10 +6,14 @@ import com.pubnub.api.endpoints.push.RemoveChannelsFromPush
import com.pubnub.api.enums.PNOperationType
import com.pubnub.api.enums.PNPushEnvironment
import com.pubnub.api.enums.PNPushType
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.push.PNPushRemoveChannelResult
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.EndpointCore
import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.toCsv
import retrofit2.Call
import retrofit2.Response
@@ -26,6 +30,8 @@ class RemoveChannelsFromPushEndpoint internal constructor(
override val topic: String? = null,
override val environment: PNPushEnvironment = PNPushEnvironment.DEVELOPMENT,
) : EndpointCore(pubnub), RemoveChannelsFromPush {
+ private val log: PNLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+
override fun getAffectedChannels() = channels
override fun validateParams() {
@@ -42,6 +48,22 @@ class RemoveChannelsFromPushEndpoint internal constructor(
}
override fun doWork(queryParams: HashMap): Call {
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Object(
+ message = mapOf(
+ "pushType" to pushType,
+ "channels" to channels,
+ "deviceId" to deviceId,
+ "topic" to (topic ?: ""),
+ "environment" to environment,
+ "queryParams" to queryParams
+ )
+ ),
+ details = "RemoveChannelsFromPush API call",
+ )
+ )
+
addQueryParams(queryParams)
return if (pushType != PNPushType.APNS2) {
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/eventengine/EffectDispatcher.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/eventengine/EffectDispatcher.kt
index 4bae3d469f..8fc14a284c 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/eventengine/EffectDispatcher.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/eventengine/EffectDispatcher.kt
@@ -1,6 +1,9 @@
package com.pubnub.internal.eventengine
-import org.slf4j.LoggerFactory
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
+import com.pubnub.internal.logging.LoggerManager
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
@@ -8,10 +11,11 @@ import java.util.concurrent.Executors
internal class EffectDispatcher(
private val effectFactory: EffectFactory,
private val effectSource: Source,
+ private val logConfig: LogConfig,
private val managedEffects: ConcurrentHashMap = ConcurrentHashMap(),
- private val executorService: ExecutorService = Executors.newSingleThreadExecutor(),
+ private val executorService: ExecutorService = Executors.newSingleThreadExecutor()
) {
- private val log = LoggerFactory.getLogger(EffectDispatcher::class.java)
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
fun start() {
executorService.submit {
@@ -31,7 +35,8 @@ internal class EffectDispatcher(
}
internal fun dispatch(effectInvocation: T) {
- log.trace("Dispatching effect: $effectInvocation")
+ log.trace(LogMessage(message = LogMessageContent.Text("Dispatching effect: $effectInvocation")))
+
when (val type = effectInvocation.type) {
is Cancel -> {
managedEffects.remove(type.idToCancel)?.cancel()
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/eventengine/EventEngine.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/eventengine/EventEngine.kt
index 715671282c..eea0fc90c1 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/eventengine/EventEngine.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/eventengine/EventEngine.kt
@@ -1,6 +1,9 @@
package com.pubnub.internal.eventengine
-import org.slf4j.LoggerFactory
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
+import com.pubnub.internal.logging.LoggerManager
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
@@ -8,9 +11,10 @@ internal class EventEngine,
private val eventSource: Source,
private var currentState: S,
+ private val logConfig: LogConfig,
private val executorService: ExecutorService = Executors.newSingleThreadExecutor(),
) {
- private val log = LoggerFactory.getLogger(EventEngine::class.java)
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
fun start() {
executorService.submit {
@@ -31,11 +35,24 @@ internal class EventEngine effectSink.add(invocation) }
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/eventengine/State.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/eventengine/State.kt
index 17914311bf..55afe1d45a 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/eventengine/State.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/eventengine/State.kt
@@ -1,12 +1,6 @@
package com.pubnub.internal.eventengine
-import org.slf4j.LoggerFactory
-
internal interface State> {
- companion object {
- internal val logger = LoggerFactory.getLogger(this::class.java)
- }
-
fun onEntry(): Set = setOf()
fun onExit(): Set = setOf()
@@ -20,11 +14,6 @@ internal fun > S.transit
state: S,
vararg invocations: Ei,
): Pair> {
- State.logger.trace(
- "Transitioning from ${this::class.simpleName} to ${state::class.simpleName} with ${invocations.size} " +
- "invocations: ${invocations.joinToString(", ")}",
- )
-
val effectInvocations = this.onExit() + invocations + state.onEntry()
return Pair(state, effectInvocations)
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/extension/JsonElement.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/extension/JsonElement.kt
index 22f1b7c1bc..b5479abab2 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/extension/JsonElement.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/extension/JsonElement.kt
@@ -3,20 +3,20 @@ package com.pubnub.internal.extension
import com.google.gson.JsonElement
import com.pubnub.api.PubNubError
import com.pubnub.api.crypto.CryptoModule
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.internal.crypto.decryptString
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.managers.MapperManager
-import org.slf4j.LoggerFactory
-
-private val log = LoggerFactory.getLogger("JsonElement")
private const val PN_OTHER = "pn_other"
internal fun JsonElement.tryDecryptMessage(
cryptoModule: CryptoModule?,
mapper: MapperManager,
+ logger: PNLogger,
): Pair {
cryptoModule ?: return this to null
-
val inputText =
if (mapper.isJsonObject(this)) {
// property pn_other is used when we want to send encrypted Push Notification, not whole JSON object is encrypted but only value of pn_other property
@@ -25,21 +25,21 @@ internal fun JsonElement.tryDecryptMessage(
mapper.elementToString(this, PN_OTHER)
} else {
// plain JSON object indicates that this is not encrypted message
- return this to logAndReturnDecryptionError()
+ return this to logAndReturnDecryptionError(logger)
}
} else if (isJsonPrimitive && asJsonPrimitive.isString) {
// String may represent not encrypted string or encrypted data. We will check this when decrypting.
mapper.elementToString(this)
} else {
// Input represents some other Json structure, such as JsonArray
- return this to logAndReturnDecryptionError()
+ return this to logAndReturnDecryptionError(logger)
}
val outputText =
try {
cryptoModule.decryptString(inputText!!)
} catch (e: Exception) {
- return this to logAndReturnDecryptionError()
+ return this to logAndReturnDecryptionError(logger)
}
var outputObject = mapper.fromJson(outputText, JsonElement::class.java)
@@ -53,8 +53,13 @@ internal fun JsonElement.tryDecryptMessage(
return outputObject to null
}
-private fun logAndReturnDecryptionError(): PubNubError {
+private fun logAndReturnDecryptionError(logger: PNLogger): PubNubError {
val pnError = PubNubError.CRYPTO_IS_CONFIGURED_BUT_MESSAGE_IS_NOT_ENCRYPTED
- log.warn(pnError.message)
+ logger.warn(
+ LogMessage(
+ message = LogMessageContent.Text(pnError.message),
+ location = "JsonElement.tryDecryptMessage",
+ )
+ )
return pnError
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/CompositeLogger.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/CompositeLogger.kt
new file mode 100644
index 0000000000..801476c5bf
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/CompositeLogger.kt
@@ -0,0 +1,168 @@
+package com.pubnub.internal.logging
+
+import com.pubnub.api.logging.CustomLogger
+import com.pubnub.api.logging.ErrorDetails
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
+import com.pubnub.api.logging.LogMessageType
+import com.pubnub.internal.logging.networkLogging.simplified
+import org.slf4j.Logger
+import org.slf4j.event.Level
+
+/**
+ * Composite logger that delegates to multiple loggers.
+ * Ensures all loggers receive the same messages.
+ */
+class CompositeLogger(
+ private val slf4jLogger: Logger,
+ private val location: String,
+ private val pnInstanceId: String,
+ private val toPortalLogger: PNLogger? = null,
+ private val customLoggers: List? = null,
+) : PNLogger {
+ override fun trace(message: LogMessage) {
+ val enhancedLogMessage = LogMessage(
+ message = message.message,
+ details = message.details,
+ type = message.type,
+ location = message.location ?: location,
+ pubNubId = pnInstanceId,
+ logLevel = Level.TRACE,
+ timestamp = message.timestamp
+ )
+ slf4jLogger.trace(enhancedLogMessage.simplified())
+ toPortalLogger?.trace(enhancedLogMessage)
+ delegateToCustomLoggers { logger: CustomLogger ->
+ sendMessageToCustomLogger(logger, enhancedLogMessage)
+ }
+ }
+
+ override fun debug(message: LogMessage) {
+ val enhancedLogMessage = LogMessage(
+ message = message.message,
+ details = message.details,
+ type = message.type,
+ location = message.location ?: location,
+ pubNubId = pnInstanceId,
+ logLevel = Level.DEBUG,
+ timestamp = message.timestamp
+ )
+ slf4jLogger.debug(enhancedLogMessage.simplified())
+ toPortalLogger?.debug(enhancedLogMessage)
+ delegateToCustomLoggers { logger: CustomLogger ->
+ sendMessageToCustomLogger(logger, enhancedLogMessage)
+ }
+ }
+
+ override fun info(message: LogMessage) {
+ val enhancedLogMessage = LogMessage(
+ message = message.message,
+ details = message.details,
+ type = message.type,
+ location = message.location ?: location,
+ pubNubId = pnInstanceId,
+ logLevel = Level.INFO,
+ timestamp = message.timestamp
+ )
+ slf4jLogger.info(enhancedLogMessage.simplified())
+ toPortalLogger?.info(enhancedLogMessage)
+ delegateToCustomLoggers { logger: CustomLogger ->
+ sendMessageToCustomLogger(logger, enhancedLogMessage)
+ }
+ }
+
+ override fun warn(message: LogMessage) {
+ val enhancedLogMessage = LogMessage(
+ message = message.message,
+ details = message.details,
+ type = message.type,
+ location = message.location ?: location,
+ pubNubId = pnInstanceId,
+ logLevel = Level.WARN,
+ timestamp = message.timestamp
+ )
+ slf4jLogger.warn(enhancedLogMessage.simplified())
+ toPortalLogger?.warn(enhancedLogMessage)
+ delegateToCustomLoggers { logger: CustomLogger ->
+ sendMessageToCustomLogger(logger, enhancedLogMessage)
+ }
+ }
+
+ override fun error(message: LogMessage) {
+ val enhancedLogMessage = LogMessage(
+ message = message.message,
+ details = message.details,
+ type = message.type,
+ location = message.location ?: location,
+ pubNubId = pnInstanceId,
+ logLevel = Level.ERROR,
+ timestamp = message.timestamp
+ )
+ slf4jLogger.error(enhancedLogMessage.simplified())
+ toPortalLogger?.error(enhancedLogMessage)
+ delegateToCustomLoggers { logger: CustomLogger ->
+ sendMessageToCustomLogger(logger, enhancedLogMessage)
+ }
+ }
+
+ private fun sendMessageToCustomLogger(logger: CustomLogger, message: LogMessage) {
+ when (message.logLevel) {
+ Level.TRACE -> {
+ logger.trace(logMessage = message)
+ logger.trace(message = message.simplified())
+ }
+
+ Level.DEBUG -> {
+ logger.debug(logMessage = message)
+ logger.debug(message = message.simplified())
+ }
+
+ Level.INFO -> {
+ logger.info(logMessage = message)
+ logger.info(message = message.simplified())
+ }
+
+ Level.WARN -> {
+ logger.warn(logMessage = message)
+ logger.warn(message = message.simplified())
+ }
+
+ Level.ERROR -> {
+ logger.error(logMessage = message)
+ logger.error(message = message.simplified())
+ }
+
+ else -> throw IllegalArgumentException("Unsupported log level: ${message.logLevel}")
+ }
+ }
+
+ private inline fun delegateToCustomLoggers(action: (CustomLogger) -> Unit) {
+ customLoggers?.forEach { logger ->
+ try {
+ action(logger)
+ } catch (e: Exception) {
+ // Log through primary logger if custom logger fails
+ // but don't let it crash the logging system
+ try {
+ val logMessage = LogMessage(
+ message = LogMessageContent.Error(
+ ErrorDetails(
+ type = this::class.java.simpleName,
+ message = "Custom logger ${logger.name} failed: ${e.message}",
+ )
+ ),
+ type = LogMessageType.ERROR,
+ location = "CompositeLogger",
+ pubNubId = pnInstanceId,
+ logLevel = Level.ERROR
+ )
+ slf4jLogger.error(logMessage.simplified())
+ toPortalLogger?.error(logMessage)
+ } catch (ignored: Exception) {
+ // If even primary logger fails, there's nothing more we can do
+ // Don't let logging crash the application
+ }
+ }
+ }
+ }
+}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/ConfigurationLogger.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/ConfigurationLogger.kt
new file mode 100644
index 0000000000..da239dedd5
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/ConfigurationLogger.kt
@@ -0,0 +1,99 @@
+package com.pubnub.internal.logging
+
+import com.pubnub.api.enums.PNLogVerbosity
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
+import com.pubnub.api.v2.PNConfiguration
+
+private const val NOT_SET = "not set"
+
+object ConfigurationLogger {
+ fun logConfiguration(
+ configuration: PNConfiguration,
+ logger: PNLogger,
+ instanceId: String,
+ className: Class<*>
+ ) {
+ val configSummary = mapOf(
+ // Required parameters
+ "userId" to configuration.userId.value,
+ "subscribeKey" to configuration.subscribeKey,
+ // Optional parameters
+ "publishKey" to (configuration.publishKey.takeIf { it.isNotBlank() } ?: NOT_SET),
+ "secretKey" to (configuration.secretKey.takeIf { it.isNotBlank() }?.let { "set: *****" } ?: NOT_SET),
+ // Security and connection settings
+ "secure" to configuration.secure,
+ "origin" to (configuration.origin.takeIf { it.isNotBlank() } ?: "default"),
+ "logVerbosity" to (configuration.logVerbosity.takeIf { it == PNLogVerbosity.BODY }?.let { "(Deprecated) ${it.name}" } ?: NOT_SET),
+ "cacheBusting" to configuration.cacheBusting,
+ // Timeout configurations
+ "connectTimeout" to configuration.connectTimeout,
+ "subscribeTimeout" to configuration.subscribeTimeout,
+ "nonSubscribeReadTimeout" to configuration.nonSubscribeReadTimeout,
+ // Presence and heartbeat settings
+ "presenceTimeout" to configuration.presenceTimeout,
+ "heartbeatInterval" to configuration.heartbeatInterval,
+ "heartbeatNotificationOptions" to configuration.heartbeatNotificationOptions.name,
+ "suppressLeaveEvents" to configuration.suppressLeaveEvents,
+ "maintainPresenceState" to configuration.maintainPresenceState,
+ // Authentication
+ "authKey" to (configuration.authKey.takeIf { it.isNotBlank() }?.let { "(@Deprecated) set: *****" } ?: NOT_SET),
+ "authToken" to (configuration.authToken?.takeIf { it.isNotBlank() }?.let { "set: *****" } ?: NOT_SET),
+ // Filtering and subscriptions
+ "filterExpression" to (configuration.filterExpression.takeIf { it.isNotBlank() } ?: NOT_SET),
+ "dedupOnSubscribe" to configuration.dedupOnSubscribe,
+ "maximumMessagesCacheSize" to configuration.maximumMessagesCacheSize,
+ // Retry and reliability
+ "retryConfiguration" to (configuration.retryConfiguration.javaClass.simpleName ?: "none"),
+ "fileMessagePublishRetryLimit" to configuration.fileMessagePublishRetryLimit,
+ // Identification and tracking
+ "includeInstanceIdentifier" to configuration.includeInstanceIdentifier,
+ "includeRequestIdentifier" to configuration.includeRequestIdentifier,
+ "pnsdkSuffixes" to (configuration.pnsdkSuffixes.takeIf { it.isNotEmpty() } ?: NOT_SET),
+ // Crypto and encryption
+ "cryptoModule" to (
+ if (configuration.cryptoModule != null) {
+ "enabled"
+ } else {
+ "disabled"
+ }
+ ),
+ // Manual presence management
+ "managePresenceListManually" to (configuration.managePresenceListManually ?: NOT_SET),
+ // Logging configuration
+ "customLoggers" to (
+ configuration.customLoggers?.let {
+ "enabled (${it.size} logger${if (it.size != 1) {
+ "s"
+ } else {
+ ""
+ }})"
+ } ?: NOT_SET
+ ),
+ // Network and proxy settings
+ "proxy" to (configuration.proxy?.toString() ?: NOT_SET),
+ "proxySelector" to (configuration.proxySelector?.toString() ?: NOT_SET),
+ "proxyAuthenticator" to (configuration.proxyAuthenticator?.toString() ?: NOT_SET),
+ "maximumConnections" to (configuration.maximumConnections?.toString() ?: NOT_SET),
+ "httpLoggingInterceptor" to (configuration.httpLoggingInterceptor?.let { "(@Deprecated) enabled (${it.level})" } ?: NOT_SET),
+ // SSL/TLS settings
+ "sslSocketFactory" to (configuration.sslSocketFactory?.toString() ?: NOT_SET),
+ "x509ExtendedTrustManager" to (configuration.x509ExtendedTrustManager?.toString() ?: NOT_SET),
+ "connectionSpec" to (configuration.connectionSpec?.toString() ?: NOT_SET),
+ "hostnameVerifier" to (configuration.hostnameVerifier?.toString() ?: NOT_SET),
+ "certificatePinner" to (configuration.certificatePinner?.toString() ?: NOT_SET),
+ // App Engine settings
+ "googleAppEngineNetworking" to configuration.googleAppEngineNetworking,
+ // Instance identification
+ "instanceId" to instanceId
+ )
+
+ logger.debug(
+ LogMessage(
+ message = LogMessageContent.Object(message = configSummary),
+ details = "Configuration logged",
+ location = className.toString(),
+ )
+ )
+ }
+}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/LogConfigFromPortal.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/LogConfigFromPortal.kt
new file mode 100644
index 0000000000..e7d607cc4b
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/LogConfigFromPortal.kt
@@ -0,0 +1,13 @@
+package com.pubnub.internal.logging
+
+import org.slf4j.event.Level
+
+/**
+ * Immutable configuration loaded from portal for logging behavior.
+ * Thread-safe value object that represents portal-side logging configuration.
+ *
+ * @param isLoggingEnabled Whether logging to portal is enabled
+ * @param logLevel The minimum log level to send to portal
+ * @param userId The user ID for which logging is enabled
+ */
+class LogConfigFromPortal(val isLoggingEnabled: Boolean, val logLevel: Level, val userId: String)
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/LoggerManager.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/LoggerManager.kt
new file mode 100644
index 0000000000..eb439c0e84
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/LoggerManager.kt
@@ -0,0 +1,88 @@
+package com.pubnub.internal.logging
+
+import com.pubnub.api.logging.LogConfig
+import org.slf4j.Logger
+
+/**
+ * Manages logger creation with dependency injection support for better testability.
+ * Ensures logging never fails the application by providing fallback mechanisms.
+ *
+ * This class is fully thread-safe and can be used concurrently from multiple threads
+ */
+class LoggerManager(
+ private val loggerFactory: (Class<*>) -> Logger = { org.slf4j.LoggerFactory.getLogger(it) },
+) {
+ /**
+ * Creates a logger for the given configuration and class.
+ * Returns a fallback logger if creation fails to prevent application crashes.
+ */
+ fun getLogger(logConfig: LogConfig, clazz: Class<*>): PNLogger {
+ return try {
+ createLogger(logConfig, clazz)
+ } catch (e: Exception) {
+ // Return fallback logger if creation fails
+ createFallbackLogger(clazz, e)
+ }
+ }
+
+ private fun createLogger(logConfig: LogConfig, clazz: Class<*>): PNLogger {
+ val slf4jLogger: Logger = loggerFactory(clazz)
+// val toPortalLogger = ToPortalLogger(userId = logConfig.userId) // todo enable when ready
+ return CompositeLogger(
+ slf4jLogger,
+ clazz.simpleName,
+ logConfig.pnInstanceId,
+ null,
+ logConfig.customLoggers
+ )
+ }
+
+ private fun createFallbackLogger(clazz: Class<*>, cause: Exception): PNLogger {
+ // Try to create a basic SLF4J logger as fallback
+ return try {
+ val fallbackSlf4jLogger = org.slf4j.LoggerFactory.getLogger(clazz)
+ fallbackSlf4jLogger.warn("Failed to create portal logger. Using fallback", cause)
+
+ // Create a minimal logger
+ CompositeLogger(fallbackSlf4jLogger, location = clazz.simpleName, pnInstanceId = "fallback-instance")
+ } catch (fallbackException: Exception) {
+ // If even SLF4J fails, return no-op logger
+ NoOpLogger(clazz)
+ }
+ }
+
+ companion object {
+ /**
+ * Default instance for backwards compatibility.
+ */
+ @JvmStatic
+ val instance = LoggerManager()
+ }
+}
+
+/**
+ * No-operation logger implementation used as last resort fallback.
+ * Ensures logging calls never crash the application.
+ */
+private class NoOpLogger(private val clazz: Class<*>) : PNLogger {
+ override fun trace(message: com.pubnub.api.logging.LogMessage) {
+ // No-op
+ }
+
+ override fun debug(message: com.pubnub.api.logging.LogMessage) {
+ // No-op
+ }
+
+ override fun info(message: com.pubnub.api.logging.LogMessage) {
+ // No-op
+ }
+
+ override fun warn(message: com.pubnub.api.logging.LogMessage) {
+ // No-op
+ }
+
+ override fun error(message: com.pubnub.api.logging.LogMessage) {
+ // Emergency fallback - print to System.err only in critical cases
+ System.err.println("CRITICAL: Logger failure in ${clazz.simpleName}: ${message.message}")
+ }
+}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/PNLogger.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/PNLogger.kt
new file mode 100644
index 0000000000..47ec743670
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/PNLogger.kt
@@ -0,0 +1,15 @@
+package com.pubnub.internal.logging
+
+import com.pubnub.api.logging.LogMessage
+
+interface PNLogger {
+ fun trace(message: LogMessage)
+
+ fun debug(message: LogMessage)
+
+ fun info(message: LogMessage)
+
+ fun warn(message: LogMessage)
+
+ fun error(message: LogMessage)
+}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/ToPortalLogger.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/ToPortalLogger.kt
new file mode 100644
index 0000000000..f71ae6aeb6
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/ToPortalLogger.kt
@@ -0,0 +1,75 @@
+package com.pubnub.internal.logging
+
+import com.pubnub.api.logging.LogMessage
+import org.slf4j.event.Level
+import org.slf4j.event.Level.DEBUG
+import org.slf4j.event.Level.ERROR
+import org.slf4j.event.Level.INFO
+import org.slf4j.event.Level.TRACE
+import org.slf4j.event.Level.WARN
+
+/**
+ * Logger implementation that sends logs to a portal.
+ */
+class ToPortalLogger(
+ private val userId: String,
+) : PNLogger {
+ override fun trace(message: LogMessage) {
+ onLog(TRACE, message)
+ }
+
+ override fun debug(message: LogMessage) {
+ onLog(DEBUG, message)
+ }
+
+ override fun info(message: LogMessage) {
+ onLog(INFO, message)
+ }
+
+ override fun warn(message: LogMessage) {
+ onLog(WARN, message)
+ }
+
+ override fun error(message: LogMessage) {
+ onLog(ERROR, message)
+ }
+
+ private fun onLog(level: Level, message: LogMessage) {
+ if (isLoggingToPortalEnabled() && shouldLogMessageForThisUser() && shouldLogMessageForThisLevel(level)) {
+ // todo implement sending to portal
+ // replace message content with calculated finger print using logic from ADR both for LogMessageType.OBJECT
+ // that is used to log details about API calls and also in NetworkRequest, NetworkResponse
+ }
+ }
+
+ private fun shouldLogMessageForThisLevel(level: Level): Boolean {
+ val configuredLevel = getConfigFromPortal().logLevel
+ return level.toInt() >= configuredLevel.toInt()
+ }
+
+ private fun isLoggingToPortalEnabled(): Boolean {
+ return getConfigFromPortal().isLoggingEnabled
+ }
+
+ private fun shouldLogMessageForThisUser(): Boolean {
+ return getConfigFromPortal().userId == userId
+ }
+
+ private fun getConfigFromPortal(): LogConfigFromPortal = portalConfig
+
+ // Thread-safe lazy configuration loading
+ private val portalConfig: LogConfigFromPortal by lazy {
+ loadConfigFromPortal()
+ }
+
+ // todo when service available replace it with configu retrival from portal
+ private fun loadConfigFromPortal(): LogConfigFromPortal {
+ // This function should retrieve the logging configuration from the portal
+ // For now, we return a default configuration
+ return LogConfigFromPortal(
+ isLoggingEnabled = false,
+ logLevel = INFO,
+ userId = "defaultUserId"
+ )
+ }
+}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/networkLogging/CustomPnHttpLoggingInterceptor.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/networkLogging/CustomPnHttpLoggingInterceptor.kt
new file mode 100644
index 0000000000..63a09dbcc5
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/networkLogging/CustomPnHttpLoggingInterceptor.kt
@@ -0,0 +1,173 @@
+package com.pubnub.internal.logging.networkLogging
+
+import com.pubnub.api.enums.PNLogVerbosity
+import com.pubnub.api.logging.ErrorDetails
+import com.pubnub.api.logging.HttpMethod
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
+import com.pubnub.api.logging.NetworkLog
+import com.pubnub.api.logging.NetworkRequestMessage
+import com.pubnub.api.logging.NetworkResponseMessage
+import com.pubnub.internal.logging.PNLogger
+import com.pubnub.internal.managers.MapperManager
+import okhttp3.Interceptor
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.ResponseBody.Companion.toResponseBody
+import java.io.IOException
+import java.util.Base64
+
+private const val PUBNUB_OKHTTP_LOG_TAG = "pubnub.okhttp"
+
+class CustomPnHttpLoggingInterceptor(
+ private val logger: PNLogger,
+ private val mapperManager: MapperManager,
+ private val logVerbosity: PNLogVerbosity,
+) : Interceptor {
+ override fun intercept(chain: Interceptor.Chain): Response {
+ val request = chain.request()
+ val requestStartTime = System.currentTimeMillis()
+ val location = request.url.pathSegments.firstOrNull() ?: "unknown"
+
+ // Log request
+ logRequest(request, location)
+
+ var response: Response? = null
+
+ try {
+ response = chain.proceed(request)
+
+ // Log response and get the modified response with cloned body
+ val modifiedResponse = logResponse(response, location)
+ return modifiedResponse
+ } catch (e: Exception) {
+ logError(request, location, e, requestStartTime)
+
+ throw e
+ }
+ }
+
+ private fun logRequest(request: Request, location: String) {
+ val url = request.url
+ val origin = "${url.scheme}://${url.host}"
+ val path = url.encodedPath + if (url.encodedQuery != null) {
+ "?${url.encodedQuery}"
+ } else {
+ ""
+ }
+
+ // Parse query parameters
+ val queryParams = url.queryParameterNames.associateWith { url.queryParameter(it) ?: "" }
+
+ // Parse headers
+ val headers = request.headers.toMap()
+
+ val networkRequest = NetworkRequestMessage(
+ origin = origin,
+ path = path,
+ query = queryParams.takeIf { it.isNotEmpty() },
+ method = HttpMethod.fromString(request.method.lowercase()),
+ headers = headers.takeIf { it.isNotEmpty() },
+ formData = null, // TODO: Parse form data if needed
+ body = request.body.toString(),
+ timeout = null, // TODO: Extract from request if available
+ )
+
+ val requestLog = NetworkLog.Request(
+ message = networkRequest,
+ canceled = false,
+ failed = false
+ )
+
+ val logMessage = LogMessage(
+ message = LogMessageContent.NetworkRequest(requestLog),
+ details = "HTTP Request",
+ location = location,
+ )
+
+ logger.debug(logMessage)
+ // to keep PNLogVerbosity.BODY functional
+ if (logVerbosity == PNLogVerbosity.BODY) {
+ val jsonMessage = mapperManager.toJson(logMessage)
+ println("[$PUBNUB_OKHTTP_LOG_TAG] REQUEST: $jsonMessage")
+ }
+ }
+
+ private fun logResponse(response: Response, location: String): Response {
+ val url = response.request.url.toString()
+ val status = response.code
+
+ // Parse headers
+ val headers = response.headers.toMap()
+
+ // Parse body and create modified response with cloned body
+ val (body, modifiedResponse) = response.body?.let { responseBody ->
+ val contentType = responseBody.contentType()?.toString() ?: ""
+
+ try {
+ if (contentType.contains("application/json") || contentType.startsWith("text/")) {
+ val bodyString = responseBody.string()
+ val clonedResponseBody = bodyString.toResponseBody(responseBody.contentType())
+ val newResponse = response.newBuilder().body(clonedResponseBody).build()
+ bodyString to newResponse
+ } else {
+ val bytes = responseBody.bytes()
+ val clonedResponseBody = bytes.toResponseBody(responseBody.contentType())
+ val newResponse = response.newBuilder().body(clonedResponseBody).build()
+ Base64.getEncoder().encodeToString(bytes) to newResponse
+ }
+ } catch (e: IOException) {
+ "[Error reading response body: ${e.message}]" to response
+ }
+ } ?: (null to response)
+
+ val networkResponse = NetworkResponseMessage(
+ url = url,
+ status = status,
+ headers = headers.takeIf { it.isNotEmpty() },
+ body = body
+ )
+
+ val responseLog = NetworkLog.Response(message = networkResponse)
+
+ val logMessage = LogMessage(
+ message = LogMessageContent.NetworkResponse(responseLog),
+ details = "HTTP Response",
+ location = location,
+ )
+
+ logger.debug(logMessage)
+ // to keep PNLogVerbosity.BODY functional
+ if (logVerbosity == PNLogVerbosity.BODY) {
+ val jsonMessage = mapperManager.toJson(logMessage)
+ println("[$PUBNUB_OKHTTP_LOG_TAG] RESPONSE: $jsonMessage")
+ }
+
+ return modifiedResponse
+ }
+
+ private fun logError(request: Request, location: String, error: Exception, requestStartTime: Long) {
+ val duration = System.currentTimeMillis() - requestStartTime
+
+ val errorDetails = LogMessageContent.Error(
+ message = ErrorDetails(
+ type = error.javaClass.simpleName,
+ message = error.message ?: "Unknown error",
+ stack = error.stackTrace.take(10).map { it.toString() }
+ )
+ )
+
+ val logMessage = LogMessage(
+ message = errorDetails,
+ details = "HTTP Request failed after ${duration}ms: ${error.message}",
+ location = location,
+ )
+
+ logger.error(logMessage)
+ // to keep PNLogVerbosity.BODY functional
+ if (logVerbosity == PNLogVerbosity.BODY) {
+ val jsonMessage = mapperManager.toJson(logMessage)
+ println("[$PUBNUB_OKHTTP_LOG_TAG] ERROR: $jsonMessage")
+ }
+ }
+}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/networkLogging/LogMessageFormatter.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/networkLogging/LogMessageFormatter.kt
new file mode 100644
index 0000000000..67e581c203
--- /dev/null
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/networkLogging/LogMessageFormatter.kt
@@ -0,0 +1,49 @@
+package com.pubnub.internal.logging.networkLogging
+
+import com.google.gson.Gson
+import com.google.gson.GsonBuilder
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
+
+/**
+ * Formatter for log messages
+ */
+object LogMessageFormatter {
+ private val prettyGson: Gson by lazy {
+ GsonBuilder().setPrettyPrinting().create()
+ }
+
+ /**
+ * Formats message content based on type.
+ * Uses cached Gson instances for better performance.
+ */
+ fun formatMessageContent(content: LogMessageContent): String {
+ return try {
+ when (content) {
+ is LogMessageContent.Text -> content.message
+ is LogMessageContent.Object -> prettyGson.toJson(content.message)
+ is LogMessageContent.Error -> {
+ val err = content.message
+ "Error(type=${err.type}, message=${err.message}, stack=${err.stack?.joinToString("\n")})"
+ }
+ is LogMessageContent.NetworkRequest -> {
+ "NetworkRequest:\n${prettyGson.toJson(content.message)}"
+ }
+ is LogMessageContent.NetworkResponse -> {
+ "NetworkResponse:\n${prettyGson.toJson(content.message)}"
+ }
+ else -> content.toString()
+ }
+ } catch (e: Exception) {
+ "Failed to format message content: ${e.message}"
+ }
+ }
+}
+
+/**
+ * Extension function to create a simplified string representation of LogMessage.
+ */
+fun LogMessage.simplified(): String {
+ val messageContent = LogMessageFormatter.formatMessageContent(this.message)
+ return "pnInstanceId: $pubNubId location: $location details: ${details ?: ""}\n$messageContent"
+}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/ListenerManager.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/ListenerManager.kt
index 7d6ee822d9..13af217f41 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/ListenerManager.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/ListenerManager.kt
@@ -3,6 +3,8 @@ package com.pubnub.internal.managers
import com.pubnub.api.PubNub
import com.pubnub.api.callbacks.Listener
import com.pubnub.api.callbacks.SubscribeCallback
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.PNStatus
import com.pubnub.api.models.consumer.pubsub.PNEvent
import com.pubnub.api.models.consumer.pubsub.PNMessageResult
@@ -16,9 +18,11 @@ import com.pubnub.api.v2.callbacks.EventListener
import com.pubnub.api.v2.callbacks.StatusEmitter
import com.pubnub.api.v2.callbacks.StatusListener
import com.pubnub.api.v2.subscriptions.Subscription
+import com.pubnub.internal.PubNubImpl
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.PNLogger
import com.pubnub.internal.subscribe.eventengine.effect.MessagesConsumer
import com.pubnub.internal.subscribe.eventengine.effect.StatusConsumer
-import org.slf4j.LoggerFactory
import java.util.concurrent.CopyOnWriteArrayList
class ListenerManager(val pubnub: PubNub) : MessagesConsumer, StatusConsumer, EventEmitter, StatusEmitter {
@@ -27,7 +31,7 @@ class ListenerManager(val pubnub: PubNub) : MessagesConsumer, StatusConsumer, Ev
private val statusListeners get() = listeners.filterIsInstance()
private val eventListeners get() = listeners.filterIsInstance()
- private val log = LoggerFactory.getLogger(this.javaClass.simpleName)
+ private val log: PNLogger = LoggerManager.instance.getLogger((pubnub as PubNubImpl).logConfig, this::class.java)
/**
* Add a listener.
@@ -118,7 +122,7 @@ class ListenerManager(val pubnub: PubNub) : MessagesConsumer, StatusConsumer, Ev
try {
action(element)
} catch (e: Throwable) {
- log.warn("Uncaught exception in listener.", e)
+ log.warn(LogMessage(message = LogMessageContent.Text("Caught exception in listener: ${e.message}")))
}
}
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/MapperManager.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/MapperManager.kt
index 69e2b9538f..352e1d41cc 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/MapperManager.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/MapperManager.kt
@@ -19,7 +19,12 @@ import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter
import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
+import com.pubnub.api.logging.ErrorDetails
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.utils.PatchValue
+import com.pubnub.internal.logging.LoggerManager
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
@@ -28,7 +33,8 @@ import retrofit2.converter.gson.GsonConverterFactory
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
-class MapperManager {
+class MapperManager(private val logConfig: LogConfig) {
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
private val objectMapper: Gson
internal val converterFactory: Converter.Factory
@@ -228,7 +234,13 @@ class MapperManager {
input: JsonElement?,
clazz: Class,
): T {
- return this.objectMapper.fromJson(input, clazz) as T
+ log.debug(LogMessage(message = LogMessageContent.Text("Deserializing message content")))
+
+ val result = this.objectMapper.fromJson(input, clazz) as T
+
+ log.debug(LogMessage(message = LogMessageContent.Text("Message deserialized successfully")))
+
+ return result
}
fun convertValue(
@@ -239,8 +251,9 @@ class MapperManager {
}
fun toJson(input: Any?): String {
+ log.debug(LogMessage(message = LogMessageContent.Text("Serializing message content")))
try {
- return if (input is List<*> && input.javaClass.isAnonymousClass) {
+ val result = if (input is List<*> && input.javaClass.isAnonymousClass) {
objectMapper.toJson(input, List::class.java)
} else if (input is Map<*, *> && input.javaClass.isAnonymousClass) {
objectMapper.toJson(input, Map::class.java)
@@ -249,7 +262,21 @@ class MapperManager {
} else {
objectMapper.toJson(input)
}
+
+ log.debug(LogMessage(message = LogMessageContent.Text("Message serialized successfully")))
+
+ return result
} catch (e: JsonParseException) {
+ log.error(
+ LogMessage(
+ message = LogMessageContent.Error(
+ ErrorDetails(
+ type = e.javaClass.simpleName,
+ message = "Serialization of content failed due to: ${e.message}"
+ )
+ )
+ )
+ )
throw PubNubException(
pubnubError = PubNubError.JSON_ERROR,
errorMessage = e.message,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/RetrofitManager.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/RetrofitManager.kt
index 43a110dcbc..a32f741d1b 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/RetrofitManager.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/RetrofitManager.kt
@@ -1,9 +1,10 @@
package com.pubnub.internal.managers
-import com.pubnub.api.enums.PNLogVerbosity
import com.pubnub.api.v2.PNConfiguration
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.interceptor.SignatureInterceptor
+import com.pubnub.internal.logging.LoggerManager
+import com.pubnub.internal.logging.networkLogging.CustomPnHttpLoggingInterceptor
import com.pubnub.internal.services.AccessManagerService
import com.pubnub.internal.services.ChannelGroupService
import com.pubnub.internal.services.FilesService
@@ -20,7 +21,6 @@ import com.pubnub.internal.services.TimeService
import com.pubnub.internal.vendor.AppEngineFactory.Factory
import okhttp3.Call
import okhttp3.OkHttpClient
-import okhttp3.logging.HttpLoggingInterceptor
import org.jetbrains.annotations.TestOnly
import org.slf4j.LoggerFactory
import org.slf4j.helpers.NOPLoggerFactory
@@ -28,11 +28,10 @@ import retrofit2.Retrofit
import java.util.concurrent.ExecutorService
import java.util.concurrent.TimeUnit
-private const val PUBNUB_OKHTTP_REQUEST_RESPONSE_LOGGER_NAME = "pubnub.okhttp"
-
class RetrofitManager(
val pubnub: PubNubImpl,
private val configuration: PNConfiguration,
+ // todo make private
@get:TestOnly internal var transactionClientInstance: OkHttpClient? = null,
@get:TestOnly internal var subscriptionClientInstance: OkHttpClient? = null,
@get:TestOnly internal var noSignatureClientInstance: OkHttpClient? = null,
@@ -110,22 +109,17 @@ class RetrofitManager(
.connectTimeout(configuration.connectTimeout.toLong(), TimeUnit.SECONDS)
with(configuration) {
- if (logVerbosity == PNLogVerbosity.BODY) {
- okHttpBuilder.addInterceptor(
- HttpLoggingInterceptor { message ->
- if (slf4jIsBound()) {
- // will follow whatever SLF4J config (logback, log4j2, etc.) is on the classpath
- LoggerFactory.getLogger(PUBNUB_OKHTTP_REQUEST_RESPONSE_LOGGER_NAME).debug(message)
- } else {
- // fallback: always print
- println("[$PUBNUB_OKHTTP_REQUEST_RESPONSE_LOGGER_NAME] $message")
- }
- }.apply {
- level = HttpLoggingInterceptor.Level.BODY
- }
- )
+ okHttpBuilder.interceptors().removeAll { interceptor ->
+ interceptor is CustomPnHttpLoggingInterceptor
}
+ // todo detect that this is publish to portal and not log this to avoid recursion
+ // Replace the standard HttpLoggingInterceptor with our custom one
+ val customLogger = LoggerManager.instance.getLogger(pubnub.logConfig, this::class.java)
+ okHttpBuilder.addInterceptor(
+ CustomPnHttpLoggingInterceptor(customLogger, pubnub.mapper, logVerbosity)
+ )
+
if (httpLoggingInterceptor != null) {
okHttpBuilder.addInterceptor(httpLoggingInterceptor!!)
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/Presence.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/Presence.kt
index 98dd63d3e5..3ef3f3ae08 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/Presence.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/Presence.kt
@@ -3,9 +3,13 @@ package com.pubnub.internal.presence
import com.pubnub.api.PubNubException
import com.pubnub.api.enums.PNHeartbeatNotificationOptions
import com.pubnub.api.enums.PNStatusCategory
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.PNStatus
import com.pubnub.internal.eventengine.EffectDispatcher
import com.pubnub.internal.eventengine.EventEngineConf
+import com.pubnub.internal.logging.LoggerManager
import com.pubnub.internal.managers.ListenerManager
import com.pubnub.internal.managers.PresenceEventEngineManager
import com.pubnub.internal.presence.eventengine.PresenceEventEngine
@@ -15,7 +19,6 @@ import com.pubnub.internal.presence.eventengine.effect.PresenceEffectInvocation
import com.pubnub.internal.presence.eventengine.effect.effectprovider.HeartbeatProvider
import com.pubnub.internal.presence.eventengine.effect.effectprovider.LeaveProvider
import com.pubnub.internal.presence.eventengine.event.PresenceEvent
-import org.slf4j.LoggerFactory
import java.util.concurrent.ScheduledExecutorService
import kotlin.time.Duration
@@ -32,6 +35,7 @@ internal interface Presence {
presenceData: PresenceData = PresenceData(),
sendStateWithHeartbeat: Boolean,
executorService: ScheduledExecutorService,
+ logConfig: LogConfig,
): Presence {
if (heartbeatInterval <= Duration.ZERO) {
return PresenceNoOp(
@@ -41,7 +45,8 @@ internal interface Presence {
listenerManager,
heartbeatNotificationOptions,
presenceData,
- sendStateWithHeartbeat
+ sendStateWithHeartbeat,
+ logConfig
)
}
@@ -56,17 +61,20 @@ internal interface Presence {
statusConsumer = listenerManager,
presenceData = presenceData,
sendStateWithHeartbeat = sendStateWithHeartbeat,
+ logConfig = logConfig,
)
val eventEngineManager = PresenceEventEngineManager(
eventEngine = PresenceEventEngine(
effectSink = eventEngineConf.effectSink,
eventSource = eventEngineConf.eventSource,
+ logConfig = logConfig,
),
eventSink = eventEngineConf.eventSink,
effectDispatcher = EffectDispatcher(
effectFactory = effectFactory,
effectSource = eventEngineConf.effectSource,
+ logConfig = logConfig,
),
).also { it.start() }
@@ -113,8 +121,9 @@ internal class PresenceNoOp(
private val heartbeatNotificationOptions: PNHeartbeatNotificationOptions,
private val presenceData: PresenceData,
private val sendStateWithHeartbeat: Boolean,
+ private val logConfig: LogConfig,
) : Presence {
- private val log = LoggerFactory.getLogger(PresenceNoOp::class.java)
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
private val channels = mutableSetOf()
private val channelGroups = mutableSetOf()
@@ -142,7 +151,12 @@ internal class PresenceNoOp(
if (heartbeatNotificationOptions == PNHeartbeatNotificationOptions.ALL ||
heartbeatNotificationOptions == PNHeartbeatNotificationOptions.FAILURES
) {
- listenerManager.announce(PNStatus(PNStatusCategory.PNHeartbeatFailed, PubNubException.from(exception)))
+ listenerManager.announce(
+ PNStatus(
+ PNStatusCategory.PNHeartbeatFailed,
+ PubNubException.from(exception)
+ )
+ )
}
}.onSuccess {
if (heartbeatNotificationOptions == PNHeartbeatNotificationOptions.ALL) {
@@ -161,7 +175,11 @@ internal class PresenceNoOp(
if (!suppressLeaveEvents && (channels.isNotEmpty() || channelGroups.isNotEmpty())) {
leaveProvider.getLeaveRemoteAction(channels, channelGroups).async { result ->
result.onFailure {
- log.error("LeaveEffect failed", it)
+ log.error(
+ LogMessage(
+ message = LogMessageContent.Text("LeaveEffect from left operation failed: $it"),
+ )
+ )
}
}
}
@@ -174,7 +192,11 @@ internal class PresenceNoOp(
if (!suppressLeaveEvents && (channels.isNotEmpty() || channelGroups.isNotEmpty())) {
leaveProvider.getLeaveRemoteAction(channels, channelGroups).async { result ->
result.onFailure {
- log.error("LeaveEffect failed", it)
+ log.error(
+ LogMessage(
+ message = LogMessageContent.Text("LeaveEffect from leftAll operation failed: $it"),
+ )
+ )
}
}
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/PresenceEventEngine.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/PresenceEventEngine.kt
index e1818d11db..e5fd344e2a 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/PresenceEventEngine.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/PresenceEventEngine.kt
@@ -1,5 +1,6 @@
package com.pubnub.internal.presence.eventengine
+import com.pubnub.api.logging.LogConfig
import com.pubnub.internal.eventengine.EventEngine
import com.pubnub.internal.eventengine.Sink
import com.pubnub.internal.eventengine.Source
@@ -12,5 +13,6 @@ internal typealias PresenceEventEngine = EventEngine,
eventSource: Source,
+ logConfig: LogConfig,
currentState: PresenceState = PresenceState.HeartbeatInactive,
-): PresenceEventEngine = EventEngine(effectSink, eventSource, currentState)
+): PresenceEventEngine = EventEngine(effectSink, eventSource, currentState, logConfig)
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/HeartbeatEffect.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/HeartbeatEffect.kt
index 01622064bf..c7efffdd1f 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/HeartbeatEffect.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/HeartbeatEffect.kt
@@ -4,23 +4,27 @@ import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.remoteaction.RemoteAction
import com.pubnub.api.enums.PNHeartbeatNotificationOptions
import com.pubnub.api.enums.PNStatusCategory
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.PNStatus
import com.pubnub.internal.eventengine.Effect
import com.pubnub.internal.eventengine.Sink
+import com.pubnub.internal.logging.LoggerManager
import com.pubnub.internal.presence.eventengine.event.PresenceEvent
import com.pubnub.internal.subscribe.eventengine.effect.StatusConsumer
-import org.slf4j.LoggerFactory
internal class HeartbeatEffect(
val heartbeatRemoteAction: RemoteAction,
val presenceEventSink: Sink,
val heartbeatNotificationOptions: PNHeartbeatNotificationOptions,
val statusConsumer: StatusConsumer,
+ private val logConfig: LogConfig,
) : Effect {
- private val log = LoggerFactory.getLogger(HeartbeatEffect::class.java)
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
override fun runEffect() {
- log.trace("Running HeartbeatEffect")
+ log.trace(LogMessage(message = LogMessageContent.Text("Running HeartbeatEffect")))
heartbeatRemoteAction.async { result ->
result.onFailure { exception ->
if (heartbeatNotificationOptions == PNHeartbeatNotificationOptions.ALL ||
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/LeaveEffect.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/LeaveEffect.kt
index 9c738c94df..9f95d498f2 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/LeaveEffect.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/LeaveEffect.kt
@@ -1,19 +1,22 @@
package com.pubnub.internal.presence.eventengine.effect
import com.pubnub.api.endpoints.remoteaction.RemoteAction
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.internal.eventengine.Effect
-import org.slf4j.LoggerFactory
+import com.pubnub.internal.logging.LoggerManager
internal class LeaveEffect(
val leaveRemoteAction: RemoteAction,
+ private val logConfig: LogConfig,
) : Effect {
- private val log = LoggerFactory.getLogger(LeaveEffect::class.java)
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
override fun runEffect() {
- log.trace("Running LeaveEffect")
+ log.trace(LogMessage(message = LogMessageContent.Text("Running LeaveEffect.")))
leaveRemoteAction.async { result ->
result.onFailure {
- log.error("LeaveEffect failed", it)
}
}
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/PresenceEffectFactory.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/PresenceEffectFactory.kt
index 46ce65cc55..496c320fbe 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/PresenceEffectFactory.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/PresenceEffectFactory.kt
@@ -1,6 +1,7 @@
package com.pubnub.internal.presence.eventengine.effect
import com.pubnub.api.enums.PNHeartbeatNotificationOptions
+import com.pubnub.api.logging.LogConfig
import com.pubnub.internal.eventengine.Effect
import com.pubnub.internal.eventengine.EffectFactory
import com.pubnub.internal.eventengine.Sink
@@ -23,6 +24,7 @@ internal class PresenceEffectFactory(
private val statusConsumer: StatusConsumer,
private val presenceData: PresenceData,
private val sendStateWithHeartbeat: Boolean,
+ private val logConfig: LogConfig,
) : EffectFactory {
override fun create(effectInvocation: PresenceEffectInvocation): Effect? {
return when (effectInvocation) {
@@ -37,7 +39,13 @@ internal class PresenceEffectFactory(
null
},
)
- HeartbeatEffect(heartbeatRemoteAction, presenceEventSink, heartbeatNotificationOptions, statusConsumer)
+ HeartbeatEffect(
+ heartbeatRemoteAction,
+ presenceEventSink,
+ heartbeatNotificationOptions,
+ statusConsumer,
+ logConfig
+ )
}
is PresenceEffectInvocation.Leave -> {
@@ -47,14 +55,14 @@ internal class PresenceEffectFactory(
effectInvocation.channels,
effectInvocation.channelGroups,
)
- LeaveEffect(leaveRemoteAction)
+ LeaveEffect(leaveRemoteAction, logConfig)
} else {
null
}
}
is PresenceEffectInvocation.Wait -> {
- WaitEffect(heartbeatInterval, presenceEventSink, executorService)
+ WaitEffect(heartbeatInterval, presenceEventSink, executorService, logConfig)
}
PresenceEffectInvocation.CancelWait,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/WaitEffect.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/WaitEffect.kt
index e0c859fc33..91caa1efe1 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/WaitEffect.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/presence/eventengine/effect/WaitEffect.kt
@@ -1,10 +1,13 @@
package com.pubnub.internal.presence.eventengine.effect
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.internal.eventengine.ManagedEffect
import com.pubnub.internal.eventengine.Sink
import com.pubnub.internal.extension.scheduleWithDelay
+import com.pubnub.internal.logging.LoggerManager
import com.pubnub.internal.presence.eventengine.event.PresenceEvent
-import org.slf4j.LoggerFactory
import java.util.concurrent.RejectedExecutionException
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.ScheduledFuture
@@ -14,8 +17,9 @@ internal class WaitEffect(
private val heartbeatInterval: Duration,
private val presenceEventSink: Sink,
private val executorService: ScheduledExecutorService,
+ private val logConfig: LogConfig,
) : ManagedEffect {
- private val log = LoggerFactory.getLogger(WaitEffect::class.java)
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
@Transient
private var cancelled: Boolean = false
@@ -25,7 +29,11 @@ internal class WaitEffect(
@Synchronized
override fun runEffect() {
- log.trace("Running WaitEffect")
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Text("Running WaitEffect."),
+ )
+ )
if (cancelled) {
return
}
@@ -36,7 +44,11 @@ internal class WaitEffect(
presenceEventSink.add(PresenceEvent.TimesUp)
}
} catch (_: RejectedExecutionException) {
- log.trace("Unable to schedule retry, PubNub was likely already destroyed.")
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Text("Unable to schedule retry, PubNub was likely already destroyed."),
+ )
+ )
}
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/retry/RetryableCallback.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/retry/RetryableCallback.kt
index 19f8a6d69f..f700efa175 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/retry/RetryableCallback.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/retry/RetryableCallback.kt
@@ -1,9 +1,12 @@
package com.pubnub.internal.retry
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.retry.RetryConfiguration
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.extension.scheduleWithDelay
-import org.slf4j.LoggerFactory
+import com.pubnub.internal.logging.LoggerManager
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
@@ -18,8 +21,9 @@ internal abstract class RetryableCallback(
private val call: Call,
private val isEndpointRetryable: Boolean,
private val executorService: ScheduledExecutorService,
+ private val logConfig: LogConfig,
) : Callback, RetryableBase(retryConfiguration, endpointGroupName) {
- private val log = LoggerFactory.getLogger(this.javaClass.simpleName)
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
private var retryCount = 0
private var exponentialMultiplier = 0.0
@@ -81,14 +85,24 @@ internal abstract class RetryableCallback(
retryCount++
val randomDelayInMillis: Int = random.nextInt(MAX_RANDOM_DELAY_IN_MILLIS)
val effectiveDelay: Duration = delay + randomDelayInMillis.milliseconds
- log.trace("Added random delay so effective retry delay is ${effectiveDelay.inWholeMilliseconds} millis")
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Text(
+ "Added random delay so effective retry delay is ${effectiveDelay.inWholeMilliseconds} millis"
+ ),
+ )
+ )
// don't want to block the main thread in case of Android so using executorService
try {
executorService.scheduleWithDelay(effectiveDelay) {
call.clone().enqueue(this)
}
} catch (_: RejectedExecutionException) {
- log.trace("Unable to schedule retry, PubNub was likely already destroyed.")
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Text("Unable to schedule retry, PubNub was likely already destroyed."),
+ )
+ )
}
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/retry/RetryableRestCaller.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/retry/RetryableRestCaller.kt
index edb6046dc7..3458bd293f 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/retry/RetryableRestCaller.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/retry/RetryableRestCaller.kt
@@ -2,11 +2,14 @@ package com.pubnub.internal.retry
import com.pubnub.api.PubNubError
import com.pubnub.api.PubNubException
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.retry.RetryConfiguration
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.internal.PubNubRetryableException
+import com.pubnub.internal.logging.LoggerManager
import okhttp3.ResponseBody.Companion.toResponseBody
-import org.slf4j.LoggerFactory
import retrofit2.Call
import retrofit2.Response
@@ -14,8 +17,10 @@ internal class RetryableRestCaller(
retryConfiguration: RetryConfiguration,
endpointGroupName: RetryableEndpointGroup,
private val isEndpointRetryable: Boolean,
+ private val logConfig: LogConfig,
) : RetryableBase(retryConfiguration, endpointGroupName) {
- private val log = LoggerFactory.getLogger(this.javaClass.simpleName)
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
+
internal lateinit var call: Call
internal fun execute(callToBeExecuted: Call): Response {
@@ -34,7 +39,11 @@ internal class RetryableRestCaller(
}
val randomDelayInMillis = random.nextInt(MAX_RANDOM_DELAY_IN_MILLIS)
val effectiveDelayInMillis = getDelayBasedOnResponse(response).inWholeMilliseconds + randomDelayInMillis
- log.trace("Added random delay so effective retry delay is $effectiveDelayInMillis")
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Text("Added random delay so effective retry delay is $effectiveDelayInMillis"),
+ )
+ )
Thread.sleep(effectiveDelayInMillis) // we want to sleep here on current thread since this is synchronous call
call = call.clone()
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/Subscribe.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/Subscribe.kt
index cd7b5c8d09..d0888d18d6 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/Subscribe.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/Subscribe.kt
@@ -65,17 +65,20 @@ internal class Subscribe(
statusConsumer = listenerManager,
presenceData = presenceData,
sendStateWithSubscribe = sendStateWithSubscribe,
+ logConfig = pubNub.logConfig
)
val subscribeEventEngine =
SubscribeEventEngine(
effectSink = eventEnginesConf.subscribe.effectSink,
eventSource = eventEnginesConf.subscribe.eventSource,
+ logConfig = pubNub.logConfig,
)
val subscribeEffectDispatcher =
EffectDispatcher(
effectFactory = subscribeEffectFactory,
effectSource = eventEnginesConf.subscribe.effectSource,
+ logConfig = pubNub.logConfig,
)
val subscribeEventEngineManager =
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/SubscribeEventEngine.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/SubscribeEventEngine.kt
index cf49d71932..2f7ac9b408 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/SubscribeEventEngine.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/SubscribeEventEngine.kt
@@ -1,5 +1,6 @@
package com.pubnub.internal.subscribe.eventengine
+import com.pubnub.api.logging.LogConfig
import com.pubnub.internal.eventengine.EventEngine
import com.pubnub.internal.eventengine.Sink
import com.pubnub.internal.eventengine.Source
@@ -12,10 +13,12 @@ internal typealias SubscribeEventEngine = EventEngine,
eventSource: Source,
+ logConfig: LogConfig,
currentState: SubscribeState = SubscribeState.Unsubscribed,
): SubscribeEventEngine =
EventEngine(
effectSink,
eventSource,
currentState,
+ logConfig
)
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/EmitMessagesEffect.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/EmitMessagesEffect.kt
index 17e6881294..9637cf1850 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/EmitMessagesEffect.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/EmitMessagesEffect.kt
@@ -1,5 +1,8 @@
package com.pubnub.internal.subscribe.eventengine.effect
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.pubsub.PNEvent
import com.pubnub.api.models.consumer.pubsub.PNMessageResult
import com.pubnub.api.models.consumer.pubsub.PNPresenceEventResult
@@ -8,16 +11,21 @@ import com.pubnub.api.models.consumer.pubsub.files.PNFileEventResult
import com.pubnub.api.models.consumer.pubsub.message_actions.PNMessageActionResult
import com.pubnub.api.models.consumer.pubsub.objects.PNObjectEventResult
import com.pubnub.internal.eventengine.Effect
-import org.slf4j.LoggerFactory
+import com.pubnub.internal.logging.LoggerManager
internal class EmitMessagesEffect(
private val messagesConsumer: MessagesConsumer,
private val messages: List,
+ private val logConfig: LogConfig,
) : Effect {
- private val log = LoggerFactory.getLogger(EmitMessagesEffect::class.java)
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
override fun runEffect() {
- log.trace("Running EmitMessagesEffect")
+ log.trace(
+ LogMessage(
+ message = LogMessageContent.Text("Running EmitMessagesEffect: Emitting ${messages.size} messages to consumers"),
+ )
+ )
for (message in messages) {
try {
when (message) {
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/EmitStatusEffect.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/EmitStatusEffect.kt
index c6387ba220..64a3ed8aba 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/EmitStatusEffect.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/EmitStatusEffect.kt
@@ -1,17 +1,21 @@
package com.pubnub.internal.subscribe.eventengine.effect
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.PNStatus
import com.pubnub.internal.eventengine.Effect
-import org.slf4j.LoggerFactory
+import com.pubnub.internal.logging.LoggerManager
internal class EmitStatusEffect(
private val statusConsumer: StatusConsumer,
private val status: PNStatus,
+ private val logConfig: LogConfig
) : Effect {
- private val log = LoggerFactory.getLogger(EmitStatusEffect::class.java)
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
override fun runEffect() {
- log.trace("Running EmitStatusEffect: $status")
+ log.trace(LogMessage(message = LogMessageContent.Text("Running EmitStatusEffect: $status")))
statusConsumer.announce(status)
}
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/HandshakeEffect.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/HandshakeEffect.kt
index 3920db49b5..512c10d50a 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/HandshakeEffect.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/HandshakeEffect.kt
@@ -2,20 +2,24 @@ package com.pubnub.internal.subscribe.eventengine.effect
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.remoteaction.RemoteAction
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.internal.eventengine.ManagedEffect
import com.pubnub.internal.eventengine.Sink
+import com.pubnub.internal.logging.LoggerManager
import com.pubnub.internal.subscribe.eventengine.event.SubscribeEvent
import com.pubnub.internal.subscribe.eventengine.event.SubscriptionCursor
-import org.slf4j.LoggerFactory
internal class HandshakeEffect(
private val handshakeRemoteAction: RemoteAction,
private val subscribeEventSink: Sink,
+ private val logConfig: LogConfig,
) : ManagedEffect {
- private val log = LoggerFactory.getLogger(HandshakeEffect::class.java)
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
override fun runEffect() {
- log.trace("Running HandshakeEffect")
+ log.trace(LogMessage(message = LogMessageContent.Text("Running HandshakeEffect")))
handshakeRemoteAction.async { result ->
result.onFailure {
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/ReceiveMessagesEffect.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/ReceiveMessagesEffect.kt
index b4c69c408b..f542795b81 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/ReceiveMessagesEffect.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/ReceiveMessagesEffect.kt
@@ -2,19 +2,23 @@ package com.pubnub.internal.subscribe.eventengine.effect
import com.pubnub.api.PubNubException
import com.pubnub.api.endpoints.remoteaction.RemoteAction
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.internal.eventengine.ManagedEffect
import com.pubnub.internal.eventengine.Sink
+import com.pubnub.internal.logging.LoggerManager
import com.pubnub.internal.subscribe.eventengine.event.SubscribeEvent
-import org.slf4j.LoggerFactory
internal class ReceiveMessagesEffect(
private val receiveMessagesRemoteAction: RemoteAction,
private val subscribeEventSink: Sink,
+ private val logConfig: LogConfig,
) : ManagedEffect {
- private val log = LoggerFactory.getLogger(ReceiveMessagesEffect::class.java)
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
override fun runEffect() {
- log.trace("Running ReceiveMessagesEffect")
+ log.trace(LogMessage(message = LogMessageContent.Text("Running ReceiveMessagesEffect")))
receiveMessagesRemoteAction.async { result ->
result.onFailure {
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/SubscribeEffectFactory.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/SubscribeEffectFactory.kt
index 61575c84f4..82ab8782d8 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/SubscribeEffectFactory.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/subscribe/eventengine/effect/SubscribeEffectFactory.kt
@@ -1,6 +1,7 @@
package com.pubnub.internal.subscribe.eventengine.effect
import com.pubnub.api.endpoints.remoteaction.RemoteAction
+import com.pubnub.api.logging.LogConfig
import com.pubnub.api.models.consumer.pubsub.PNEvent
import com.pubnub.internal.eventengine.Effect
import com.pubnub.internal.eventengine.EffectFactory
@@ -24,15 +25,16 @@ internal class SubscribeEffectFactory(
private val statusConsumer: StatusConsumer,
private val presenceData: PresenceData,
private val sendStateWithSubscribe: Boolean,
+ private val logConfig: LogConfig
) : EffectFactory {
override fun create(effectInvocation: SubscribeEffectInvocation): Effect? {
return when (effectInvocation) {
is SubscribeEffectInvocation.EmitMessages -> {
- EmitMessagesEffect(messagesConsumer, effectInvocation.messages)
+ EmitMessagesEffect(messagesConsumer, effectInvocation.messages, logConfig)
}
is SubscribeEffectInvocation.EmitStatus -> {
- EmitStatusEffect(statusConsumer, effectInvocation.status)
+ EmitStatusEffect(statusConsumer, effectInvocation.status, logConfig)
}
is SubscribeEffectInvocation.Handshake -> {
@@ -46,7 +48,7 @@ internal class SubscribeEffectFactory(
null
},
)
- HandshakeEffect(handshakeRemoteAction, subscribeEventSink)
+ HandshakeEffect(handshakeRemoteAction, subscribeEventSink, logConfig)
}
is SubscribeEffectInvocation.ReceiveMessages -> {
@@ -56,7 +58,7 @@ internal class SubscribeEffectFactory(
effectInvocation.channelGroups,
effectInvocation.subscriptionCursor,
)
- ReceiveMessagesEffect(receiveMessagesRemoteAction, subscribeEventSink)
+ ReceiveMessagesEffect(receiveMessagesRemoteAction, subscribeEventSink, logConfig)
}
SubscribeEffectInvocation.CancelHandshake,
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/PNConfigurationImpl.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/PNConfigurationImpl.kt
index c4c135a27c..a6e976d69c 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/PNConfigurationImpl.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/PNConfigurationImpl.kt
@@ -4,15 +4,17 @@ import com.pubnub.api.UserId
import com.pubnub.api.crypto.CryptoModule
import com.pubnub.api.enums.PNHeartbeatNotificationOptions
import com.pubnub.api.enums.PNLogVerbosity
+import com.pubnub.api.logging.CustomLogger
+import com.pubnub.api.logging.LogConfig
import com.pubnub.api.retry.RetryConfiguration
import com.pubnub.api.retry.RetryableEndpointGroup
import com.pubnub.api.v2.PNConfiguration
import com.pubnub.api.v2.PNConfigurationOverride
+import com.pubnub.internal.crypto.CryptoModuleImpl
import okhttp3.Authenticator
import okhttp3.CertificatePinner
import okhttp3.ConnectionSpec
import okhttp3.logging.HttpLoggingInterceptor
-import org.slf4j.LoggerFactory
import java.net.Proxy
import java.net.ProxySelector
import javax.net.ssl.HostnameVerifier
@@ -26,7 +28,7 @@ class PNConfigurationImpl(
override val secretKey: String = "",
override val authKey: String = "",
override val authToken: String? = null,
- override val cryptoModule: CryptoModule? = null,
+ override val cryptoModule: CryptoModule? = null, // don't use getter directly use getCryptoModuleWithLogConfig to be able to properly configure logging in CryptoModule
override val origin: String = "",
override val secure: Boolean = true,
override val logVerbosity: PNLogVerbosity = PNLogVerbosity.NONE,
@@ -71,6 +73,7 @@ class PNConfigurationImpl(
)
),
override val managePresenceListManually: Boolean = false,
+ override val customLoggers: List? = null,
) : PNConfiguration, PNConfigurationOverride {
companion object {
const val DEFAULT_DEDUPE_SIZE = 100
@@ -81,13 +84,26 @@ class PNConfigurationImpl(
const val CONNECT_TIMEOUT = 5
}
+ fun getCryptoModuleWithLogConfig(logConfig: LogConfig): CryptoModule? {
+ return cryptoModule?.let { module ->
+ if (module is CryptoModuleImpl) {
+ CryptoModuleImpl(
+ primaryCryptor = module.primaryCryptor,
+ cryptorsForDecryptionOnly = module.cryptorsForDecryptionOnly,
+ logConfig = logConfig
+ )
+ } else {
+ // For custom implementations, return the original instance
+ module
+ }
+ }
+ }
+
class Builder(defaultConfiguration: PNConfiguration) :
PNConfiguration.Builder,
PNConfigurationOverride.Builder {
constructor(userId: UserId, subscribeKey: String) : this(PNConfigurationImpl(userId, subscribeKey))
- private val log = LoggerFactory.getLogger(this::class.simpleName)
-
override var userId: UserId = defaultConfiguration.userId
override var subscribeKey: String = defaultConfiguration.subscribeKey
@@ -106,6 +122,15 @@ class PNConfigurationImpl(
override var secure: Boolean = defaultConfiguration.secure
+ @Deprecated(
+ message = "LogVerbosity setting is deprecated and will be removed in future versions. " +
+ "For logging configuration:\n" +
+ "1. Use an SLF4J implementation (recommended)\n" +
+ "2. Or implement CustomLogger interface and set via customLoggers property. " +
+ "Use CustomLogger if your slf4j implementation like logback, log4j2, etc. can't meet " +
+ "your specific logging requirements.",
+ level = DeprecationLevel.WARNING
+ )
override var logVerbosity: PNLogVerbosity = defaultConfiguration.logVerbosity
override var heartbeatNotificationOptions: PNHeartbeatNotificationOptions = defaultConfiguration.heartbeatNotificationOptions
@@ -114,7 +139,7 @@ class PNConfigurationImpl(
set(value) {
field =
if (value < MINIMUM_PRESENCE_TIMEOUT) {
- log.warn("Presence timeout is too low. Defaulting to: $MINIMUM_PRESENCE_TIMEOUT")
+ println("Presence timeout is too low. Defaulting to: $MINIMUM_PRESENCE_TIMEOUT")
MINIMUM_PRESENCE_TIMEOUT
} else {
value
@@ -164,6 +189,10 @@ class PNConfigurationImpl(
override var certificatePinner: CertificatePinner? = defaultConfiguration.certificatePinner
+ @Deprecated(
+ message = "This setting is deprecated. Use customLoggers instead.",
+ level = DeprecationLevel.WARNING
+ )
override var httpLoggingInterceptor: HttpLoggingInterceptor? = defaultConfiguration.httpLoggingInterceptor
override var sslSocketFactory: SSLSocketFactory? = defaultConfiguration.sslSocketFactory
@@ -183,6 +212,8 @@ class PNConfigurationImpl(
override var managePresenceListManually: Boolean = defaultConfiguration.managePresenceListManually
+ override var customLoggers: List? = defaultConfiguration.customLoggers
+
override fun build(): PNConfiguration {
return PNConfigurationImpl(
userId = userId,
@@ -224,6 +255,7 @@ class PNConfigurationImpl(
pnsdkSuffixes = pnsdkSuffixes,
retryConfiguration = retryConfiguration,
managePresenceListManually = managePresenceListManually,
+ customLoggers = customLoggers,
)
}
}
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/workers/SubscribeMessageProcessor.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/workers/SubscribeMessageProcessor.kt
index dd3021eef6..487fd47cf8 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/workers/SubscribeMessageProcessor.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/workers/SubscribeMessageProcessor.kt
@@ -2,6 +2,9 @@ package com.pubnub.internal.workers
import com.google.gson.JsonElement
import com.google.gson.JsonNull
+import com.pubnub.api.logging.LogConfig
+import com.pubnub.api.logging.LogMessage
+import com.pubnub.api.logging.LogMessageContent
import com.pubnub.api.models.consumer.files.PNDownloadableFile
import com.pubnub.api.models.consumer.message_actions.PNMessageAction
import com.pubnub.api.models.consumer.pubsub.BasePubSubResult
@@ -18,6 +21,7 @@ import com.pubnub.api.v2.PNConfiguration.Companion.isValid
import com.pubnub.internal.PubNubImpl
import com.pubnub.internal.PubNubUtil
import com.pubnub.internal.extension.tryDecryptMessage
+import com.pubnub.internal.logging.LoggerManager
import com.pubnub.internal.managers.DuplicationManager
import com.pubnub.internal.models.consumer.pubsub.objects.PNObjectEventMessage
import com.pubnub.internal.models.consumer.pubsub.objects.toApi
@@ -26,13 +30,13 @@ import com.pubnub.internal.models.server.SubscribeMessage
import com.pubnub.internal.models.server.files.FileUploadNotification
import com.pubnub.internal.services.FilesService
import com.pubnub.internal.subscribe.PRESENCE_CHANNEL_SUFFIX
-import org.slf4j.LoggerFactory
internal class SubscribeMessageProcessor(
private val pubnub: PubNubImpl,
private val duplicationManager: DuplicationManager,
+ private val logConfig: LogConfig,
) {
- private val log = LoggerFactory.getLogger("SubscribeMessageProcessor")
+ private val log = LoggerManager.instance.getLogger(logConfig, this::class.java)
companion object {
internal const val TYPE_MESSAGE = 0
@@ -89,11 +93,15 @@ internal class SubscribeMessageProcessor(
)
} else {
val (extractedMessage, error) =
- message.payload?.tryDecryptMessage(pubnub.configuration.cryptoModule, pubnub.mapper)
+ message.payload?.tryDecryptMessage(pubnub.cryptoModuleWithLogConfig, pubnub.mapper, log)
?: (null to null)
if (extractedMessage == null) {
- log.debug("unable to parse payload on #processIncomingMessages")
+ log.debug(
+ LogMessage(
+ message = LogMessageContent.Text("unable to parse payload on #processIncomingMessages"),
+ )
+ )
}
val customMessageType = message.customMessageType
diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/crypto/CryptoModuleTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/crypto/CryptoModuleTest.kt
index 129f1eb691..35c1a5fd4a 100644
--- a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/crypto/CryptoModuleTest.kt
+++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/crypto/CryptoModuleTest.kt
@@ -5,6 +5,7 @@ import com.pubnub.api.PubNubException
import com.pubnub.api.crypto.cryptor.Cryptor
import com.pubnub.api.crypto.data.EncryptedData
import com.pubnub.api.crypto.data.EncryptedStreamData
+import com.pubnub.api.logging.LogConfig
import com.pubnub.internal.crypto.CryptoModuleImpl
import com.pubnub.internal.crypto.cryptor.AesCbcCryptor
import com.pubnub.internal.crypto.cryptor.LegacyCryptor
@@ -348,6 +349,52 @@ class CryptoModuleTest {
assertEquals(input, String(decrypted.readBytes()))
}
+ @Test
+ fun `should inject LogConfig into CryptoModule created as LegacyCryptoModule`() {
+ // given
+ val cipherKey = "enigma"
+ val cryptoModule = CryptoModule.createLegacyCryptoModule(cipherKey) as CryptoModuleImpl
+ val logConfig = LogConfig(
+ pnInstanceId = "test-instance-id",
+ userId = "test-user-id"
+ )
+
+ // when
+ val cryptoModuleWithLogConfig = CryptoModuleImpl(
+ primaryCryptor = cryptoModule.primaryCryptor,
+ cryptorsForDecryptionOnly = cryptoModule.cryptorsForDecryptionOnly,
+ logConfig = logConfig
+ )
+
+ // then
+ assertEquals(logConfig, cryptoModuleWithLogConfig.logConfig)
+ assertTrue(cryptoModuleWithLogConfig.primaryCryptor is LegacyCryptor)
+ assertEquals(cryptoModule.cryptorsForDecryptionOnly, cryptoModuleWithLogConfig.cryptorsForDecryptionOnly)
+ }
+
+ @Test
+ fun `should inject LogConfig into CryptoModule created as AesCbcCryptoModule`() {
+ // given
+ val cipherKey = "enigma"
+ val cryptoModule = CryptoModule.createAesCbcCryptoModule(cipherKey) as CryptoModuleImpl
+ val logConfig = LogConfig(
+ pnInstanceId = "test-instance-id",
+ userId = "test-user-id"
+ )
+
+ // when
+ val cryptoModuleWithLogConfig = CryptoModuleImpl(
+ primaryCryptor = cryptoModule.primaryCryptor,
+ cryptorsForDecryptionOnly = cryptoModule.cryptorsForDecryptionOnly,
+ logConfig = logConfig
+ )
+
+ // then
+ assertEquals(logConfig, cryptoModuleWithLogConfig.logConfig)
+ assertTrue(cryptoModuleWithLogConfig.primaryCryptor is AesCbcCryptor)
+ assertEquals(cryptoModule.cryptorsForDecryptionOnly, cryptoModuleWithLogConfig.cryptorsForDecryptionOnly)
+ }
+
companion object {
@JvmStatic
fun decryptStreamSource(): List