C-Core (legacy) SDK 7.0.0 migration guide

New SDK available

C-Core (legacy) is still supported. If you are starting a new project, use the new C SDK.

This guide summarizes the differences between 6.X.X versions and 7.0.0 and shows how to migrate to C-Core SDK 7.0.0.

C-Core (legacy) SDK version 7.0.0 makes DNS server configuration per-context, replaces the logging subsystem with an advanced pluggable logger architecture, and adds logging methods to the C++ wrapper class. This applies to all C-Core (legacy) SDK flavors: C-Core (legacy), POSIX C, POSIX C++, Windows C, Windows C++, FreeRTOS, and Mbed.

Earlier migration guides

If you are upgrading from a version before 6.0.0, read the C-Core SDK 6.0.0 migration guide first.

What has changed​

See the major differences between versions:

FeatureC-Core SDK 6.X.XC-Core SDK 7.0.0
DNS server functionsGlobal (no context parameter)Per-context (pubnub_t* pb added as first parameter)
Logging header#include "core/pubnub_log.h"#include "core/pubnub_logger.h"
Logging functionsPUBNUB_LOG_PRINTF(...) macrospubnub_log_text(), pubnub_log_text_formatted(), pubnub_log_object(), pubnub_log_error()
Log level enumSequential: NONE=0, ERROR=1, ... TRACE=5Bitmask: TRACE=1, DEBUG=2, INFO=4, WARNING=8, ERROR=16, NONE=32
Compile-time level macroPUBNUB_LOG_LEVELPUBNUB_LOG_MIN_LEVEL
Custom output / runtime callbackOverride PUBNUB_LOG_PRINTF macro or pubnub_set_log_callback(fn)Register custom pubnub_logger_t with pubnub_logger_add(pb, logger)
WATCH_* macrosWATCH_INT(x), WATCH_STR(x), etc.Removed. Use structured logging (pubnub_log_object)
C++ wrapper (POSIX C++, Windows C++)No logging methodsNew methods: logger_add, logger_remove, set_log_level, log_text, log_object, log_error
Feature flagsAlways compiled inPUBNUB_USE_LOGGER, PUBNUB_USE_DEFAULT_LOGGER

Breaking changes​

ChangePlatforms affected
DNS server APIAll (C-Core (legacy), POSIX C, POSIX C++, Windows C, Windows C++, FreeRTOS, Mbed)
Logging subsystemAll
Log level changesAll
Build configurationAll
C++ wrapperPOSIX C++, Windows C++
Platform-specific default loggersPOSIX C, POSIX C++, Windows C, Windows C++, FreeRTOS, Microchip Harmony

DNS server API​

Applies to: All platforms

Starting with 7.0.0, all 14 DNS server functions in core/pubnub_dns_servers.h require a pubnub_t* context as their first parameter. Previously, these functions operated on global state. Now DNS server configuration is per-context.

This change affects all functions guarded by PUBNUB_SET_DNS_SERVERS.

IPv4 functions​

FunctionC-Core SDK 6.X.XC-Core SDK 7.0.0
pubnub_dns_set_primary_server_ipv4(struct pubnub_ipv4_address ipv4)(pubnub_t* pb, struct pubnub_ipv4_address ipv4)
pubnub_dns_set_secondary_server_ipv4(struct pubnub_ipv4_address ipv4)(pubnub_t* pb, struct pubnub_ipv4_address ipv4)
pubnub_dns_set_primary_server_ipv4_str(char const* ipv4_str)(pubnub_t* pb, char const* ipv4_str)
pubnub_dns_set_secondary_server_ipv4_str(char const* ipv4_str)(pubnub_t* pb, char const* ipv4_str)
pubnub_get_dns_primary_server_ipv4(struct pubnub_ipv4_address* o_ipv4)(pubnub_t* pb, struct pubnub_ipv4_address* o_ipv4)
pubnub_get_dns_secondary_server_ipv4(struct pubnub_ipv4_address* o_ipv4)(pubnub_t* pb, struct pubnub_ipv4_address* o_ipv4)
pubnub_dns_read_system_servers_ipv4(struct pubnub_ipv4_address* o_ipv4, size_t n)(pubnub_t* pb, struct pubnub_ipv4_address* o_ipv4, size_t n)

IPv6 functions (require PUBNUB_USE_IPV6)​

FunctionC-Core SDK 6.X.XC-Core SDK 7.0.0
pubnub_dns_set_primary_server_ipv6(struct pubnub_ipv6_address ipv6)(pubnub_t* pb, struct pubnub_ipv6_address ipv6)
pubnub_dns_set_secondary_server_ipv6(struct pubnub_ipv6_address ipv6)(pubnub_t* pb, struct pubnub_ipv6_address ipv6)
pubnub_dns_set_primary_server_ipv6_str(char const* ipv6_str)(pubnub_t* pb, char const* ipv6_str)
pubnub_dns_set_secondary_server_ipv6_str(char const* ipv6_str)(pubnub_t* pb, char const* ipv6_str)
pubnub_get_dns_primary_server_ipv6(struct pubnub_ipv6_address* o_ipv6)(pubnub_t* pb, struct pubnub_ipv6_address* o_ipv6)
pubnub_get_dns_secondary_server_ipv6(struct pubnub_ipv6_address* o_ipv6)(pubnub_t* pb, struct pubnub_ipv6_address* o_ipv6)
pubnub_dns_read_system_servers_ipv6N/A (new in 6.2.0)(pubnub_t* pb, struct pubnub_ipv6_address* o_ipv6, size_t n)
Fallback macros

The fallback macros (when PUBNUB_SET_DNS_SERVERS is disabled) also gained the pb parameter, so code using the macro forms also needs updating.

#include "core/pubnub_dns_servers.h"

/* DNS servers were global — no context needed */
struct pubnub_ipv4_address dns = {{8, 8, 8, 8}};
pubnub_dns_set_primary_server_ipv4(dns);
pubnub_dns_set_secondary_server_ipv4_str("8.8.4.4");

/* Read system DNS servers */
struct pubnub_ipv4_address servers[4];
int count = pubnub_dns_read_system_servers_ipv4(servers, 4);

Logging subsystem​

Applies to: All platforms

Starting with 7.0.0, the SDK replaces its legacy logging subsystem (core/pubnub_log.h) with a new advanced logging system (core/pubnub_logger.h). The new system introduces per-context logging, multiple simultaneous logger support, structured data logging, network request/response logging, and runtime log level control.

The files core/pubnub_log.h and core/pubnub_log.c are deleted. Any direct references to them cause compilation errors.

Removed APIs​

The following are deleted and cause compilation errors if referenced:

Removed APIReplacement
#include "core/pubnub_log.h"#include "core/pubnub_logger.h"
PUBNUB_LOG_PRINTF(...)pubnub_log_text_formatted(pb, level, location, format, ...)
PUBNUB_LOG_ERROR(...), PUBNUB_LOG_WARNING(...), PUBNUB_LOG_INFO(...), PUBNUB_LOG_DEBUG(...), PUBNUB_LOG_TRACE(...)pubnub_log_text_formatted(pb, level, location, format, ...)
WATCH_INT(x), WATCH_STR(x), WATCH_ENUM(x), WATCH_ULONG(x)pubnub_log_object(pb, level, location, value, details)
pubnub_set_log_callback(fn) / PUBNUB_USE_LOG_CALLBACKCreate a custom pubnub_logger_t and register with pubnub_logger_add(pb, logger). PUBNUB_USE_LOGGER controls whether the logging subsystem is compiled in.
PUBNUB_LOG_LEVEL (compile-time macro)PUBNUB_LOG_MIN_LEVEL

New logging public API​

All functions are part of the public C API in core/pubnub_logger.h.

Logger lifecycle​
FunctionDescription
pubnub_logger_alloc(vtable, user_data)Create a custom logger with a vtable and optional user data. Returns NULL on failure.
pubnub_logger_user_data(logger)Retrieve user data associated with a custom logger.
pubnub_logger_free(logger)Free a custom logger. Calls the logger's destroy() callback if provided. Sets *logger to NULL.
Logger registration​
FunctionDescription
pubnub_logger_add(pb, logger)Register a custom logger with a PubNub context. Multiple loggers can be registered. Returns 0 on success.
pubnub_logger_remove(pb, logger)Unregister a custom logger. Caller must still call pubnub_logger_free(). Returns 0 on success.
pubnub_logger_remove_all(pb)Unregister all custom loggers. Caller must free each logger individually.
Log level control​
FunctionDescription
pubnub_logger_set_log_level(pb, level)Set the minimum log level. Messages below this level are not dispatched.
pubnub_logger_log_level(pb)Get the current minimum log level. Default: PUBNUB_LOG_LEVEL_DEBUG.
Logging functions​
FunctionDescription
pubnub_log_text(pb, level, location, message)Log a plain text message.
pubnub_log_text_formatted(pb, level, location, format, ...)Log a formatted text message (printf-style).
pubnub_log_object(pb, level, location, value, details)Log a structured object/data.
pubnub_log_error(pb, location, error_code, error_message, details)Log an error. Level is always PUBNUB_LOG_LEVEL_ERROR.

Replace logging macros​

#include "core/pubnub_log.h"

PUBNUB_LOG_ERROR("Failed to publish: %d", result);
PUBNUB_LOG_DEBUG("Channel: %s", channel);

Replace PUBNUB_LOG_PRINTF override​

/* Compile-time macro override */
#define PUBNUB_LOG_PRINTF(...) my_log_func(__VA_ARGS__)

Replace pubnub_set_log_callback​

void my_callback(enum pubnub_log_level level, const char* message) {
fprintf(log_file, "[%d] %s", level, message);
}
pubnub_set_log_callback(my_callback);

Replace WATCH_* macros​

WATCH_INT(result);
WATCH_STR(channel);
Structured logging scope

All pubnub_log_value_t structures and their string pointers live on the stack. All values, containers, and the log call must be in the same scope. If a value goes out of scope before the logging function reads it, you get undefined behavior.

Log level changes​

Applies to: All platforms

The log level enum changed from sequential integers with reversed ordering to bitmask powers of 2 with natural ordering.

/* Sequential integers, REVERSED ordering (NONE is lowest) */
enum pubnub_log_level {
PUBNUB_LOG_LEVEL_NONE = 0, /* Logging disabled */
PUBNUB_LOG_LEVEL_ERROR = 1,
PUBNUB_LOG_LEVEL_WARNING = 2,
PUBNUB_LOG_LEVEL_INFO = 3,
PUBNUB_LOG_LEVEL_DEBUG = 4,
PUBNUB_LOG_LEVEL_TRACE = 5 /* Most verbose */
};
/* Filter: if (level <= PUBNUB_LOG_LEVEL) → emit */
Comparison direction changed

If your code compares log level values numerically (for example, if (level <= PUBNUB_LOG_LEVEL_INFO)), the comparison direction has changed. In the old system NONE < ERROR < TRACE. In the new system TRACE < DEBUG < INFO < WARNING < ERROR < NONE.

Build configuration​

Applies to: All platforms

Compile-time log level stripping​

The compile-time macro for log level filtering has changed.

# Old build flag
-DPUBNUB_LOG_LEVEL=PUBNUB_LOG_LEVEL_WARNING

C++ wrapper​

Applies to: POSIX C++, Windows C++

New methods are added to the pubnub::context class in cpp/pubnub_common.hpp, guarded by #if PUBNUB_USE_LOGGER. These delegate directly to the C public API functions.

MethodDescription
logger_add(pubnub_logger_t* logger)Register a custom logger. Returns 0 on success.
logger_remove(pubnub_logger_t* logger)Unregister a custom logger. Returns 0 on success.
logger_remove_all()Unregister all custom loggers.
set_log_level(pubnub_log_level level)Set minimum log level for this context.
log_level()Get current minimum log level. Default: PUBNUB_LOG_LEVEL_DEBUG.
log_text(pubnub_log_level level, char const* location, char const* message)Log a plain text message.
log_text(pubnub_log_level level, char const* location, std::string const& message)Log a text message from std::string.
log_object(pubnub_log_level level, char const* location, pubnub_log_value_t const* message, char const* details)Log a structured object with optional details.
log_error(char const* location, int error_code, char const* error_message, char const* details)Log an error (always PUBNUB_LOG_LEVEL_ERROR).

Basic C++ logging​

#include "pubnub_common.hpp"

pubnub::context ctx("demo", "demo");

/* Log simple text messages */
ctx.log_text(PUBNUB_LOG_LEVEL_INFO,
"main.cpp:10",
"PubNub context initialized");

/* Log with std::string */
std::string msg = "Subscribing to channel: " + channel_name;
ctx.log_text(PUBNUB_LOG_LEVEL_DEBUG, "main.cpp:15", msg);

/* Log an error */
ctx.log_error("main.cpp:25", -1, "Connection failed", "Timeout after 30s");

Custom logger in C++​

#include "pubnub_common.hpp"
#include "core/pubnub_logger.h"

static void my_info_handler(const pubnub_logger_t* logger,
const pubnub_log_message_t* message) {
if (message->message_type == PUBNUB_LOG_MESSAGE_TYPE_TEXT) {
const pubnub_log_message_text_t* text =
(const pubnub_log_message_text_t*)message;
std::cout << "[INFO] " << text->message << std::endl;
}
}

static const struct pubnub_logger_interface my_vtable = {
.trace = NULL,
.debug = NULL,
show all 37 lines

Feature flags​

Two new macros control the logging subsystem. Both are defined in each platform's pubnub_config.h and default to 1 (enabled).

MacroDefaultDescription
PUBNUB_USE_LOGGER1Enable/disable the entire logging subsystem. When 0, all logging macros become no-ops and logger API functions are not compiled.
PUBNUB_USE_DEFAULT_LOGGER1Enable/disable the built-in default platform logger. When 0, no logger is registered automatically — you must register your own via pubnub_logger_add().

New source files​

If you maintain custom build scripts or Makefiles, add the following files.

Always required when PUBNUB_USE_LOGGER=1​
FilePurpose
core/pubnub_logger.cPublic logger API implementation
core/pbcc_logger_manager.cLogger manager (dispatches to registered loggers)
core/pubnub_log_value.cStructured log value types
Required only when PUBNUB_USE_DEFAULT_LOGGER=1​

Add exactly one platform-specific default logger:

PlatformFile
POSIX / Windowscore/pubnub_stdio_logger.c
FreeRTOSfreertos/pubnub_freertos_logger.c
Microchip Harmonymicrochip_harmony/pubnub_harmony_logger.c

Platform-specific default loggers​

Applies to: All platforms (each platform uses its own logger implementation)

When PUBNUB_USE_DEFAULT_LOGGER is 1 (default), each new PubNub context automatically registers a platform-appropriate logger.

PlatformFileOutputTimestamps
POSIX / Windowscore/pubnub_stdio_logger.cfprintf(stdout) for TRACE/DEBUG/INFO/WARN; fprintf(stderr) for ERRORISO 8601 with milliseconds
FreeRTOSfreertos/pubnub_freertos_logger.cprintf() for all levelsISO 8601 when wall-clock available; xTaskGetTickCount() tick-based fallback
Microchip Harmonymicrochip_harmony/pubnub_harmony_logger.cSYS_CONSOLE_PRINT() for all levelsRaw Unix timestamp; SYS_TMR_TickCountGet() fallback
Output format example (POSIX/Windows)​
2026-03-03T10:11:31.456Z PubNub-a1b2c3d4 DEBUG core/pubnub_coreapi.c:123 Publishing to channel 'my-channel'

Migration steps​

To migrate to C-Core SDK 7.0.0:

  1. Update DNS server function calls. Add pubnub_t* context as the first argument to all DNS server functions:

    ActionDescription
    Add pb as the first argument to all pubnub_dns_set_*, pubnub_get_dns_*, and pubnub_dns_read_system_servers_* callsAll 14 DNS functions (7 IPv4 + 7 IPv6) now require a pubnub_t* context. This also applies to fallback macros when PUBNUB_SET_DNS_SERVERS is disabled.
  2. Update logging includes:

    ActionDescription
    Replace #include "core/pubnub_log.h" with #include "core/pubnub_logger.h"The old header file is deleted. For structured log values and convenience macros, also include core/pubnub_log_value.h.
  3. Replace old logging macros with public API functions:

    ActionDescription
    Replace PUBNUB_LOG_ERROR(...), PUBNUB_LOG_WARNING(...), etc. with pubnub_log_text_formatted()The new function requires a pubnub_t* context, a log level, a location string, and a format string with arguments.
    Replace pubnub_log_text() for non-formatted messagesUse when you don't need printf-style formatting.
  4. Replace PUBNUB_LOG_PRINTF override with runtime custom logger registration:

    ActionDescription
    Remove #define PUBNUB_LOG_PRINTF(...) overridesCreate a pubnub_logger_interface vtable and register a custom logger at runtime using pubnub_logger_alloc() and pubnub_logger_add().
  5. Replace pubnub_set_log_callback with custom logger:

    ActionDescription
    Remove pubnub_set_log_callback() callsCreate a custom logger with a vtable and register it with pubnub_logger_add(). Use pubnub_logger_user_data() to access custom state from within callbacks.
  6. Replace WATCH_* macros with structured logging:

    ActionDescription
    Replace WATCH_INT(x), WATCH_STR(x), etc.Use pubnub_log_value_t types and pubnub_log_object(). Convenience macros like PUBNUB_LOG_MAP_SET_NUMBER and PUBNUB_LOG_MAP_SET_STRING are available in core/pubnub_log_value.h.
  7. Update compile-time level configuration:

    ActionDescription
    Replace -DPUBNUB_LOG_LEVEL=PUBNUB_LOG_LEVEL_WARNING with -DPUBNUB_LOG_MIN_LEVEL=WARNINGThe new macro uses short level names: TRACE, DEBUG, INFO, WARNING, ERROR, NONE.
  8. Update runtime level filtering:

    ActionDescription
    Use pubnub_logger_set_log_level(pb, level) to control runtime filteringThe old system only supported compile-time filtering. The new system supports both compile-time stripping and runtime filtering per context.
  9. (C++ only) Use new context methods for logging:

    ActionDescription
    Use ctx.logger_add(), ctx.set_log_level(), ctx.log_text(), etc.The pubnub::context class in pubnub_common.hpp provides C++ wrappers for all logging API functions. No include changes needed — core/pubnub_logger.h is automatically included when PUBNUB_USE_LOGGER is enabled.
  10. Update build scripts. Add new source files if you maintain custom build scripts:

    ActionDescription
    Add core/pubnub_logger.c, core/pbcc_logger_manager.c, core/pubnub_log_value.cAlways required when PUBNUB_USE_LOGGER=1 (default).
    Add exactly one platform-specific default logger fileRequired when PUBNUB_USE_DEFAULT_LOGGER=1 (default). See New source files for platform-specific file names.
  11. Clean up custom loggers before freeing the PubNub context:

    ActionDescription
    Call pubnub_logger_remove(pb, logger) and pubnub_logger_free(&logger) before pubnub_free(pb)Custom loggers must be unregistered and freed before the context is freed. pubnub_logger_free() calls the logger's destroy() callback if provided.
  12. Test your application. Pay special attention to DNS configuration, logging output, and any custom logging integrations.

Additional resources​

For API details, see the C-Core (legacy) SDK documentation. For the full logging reference, see Logging. For questions or issues, contact PubNub support.

Was this page useful?

Last updated on