Skip to content

Add centralized plugin logging for Python and native plugins#64

Merged
thiagoralves merged 2 commits into
developmentfrom
fix/plugin-centralized-logging
Jan 7, 2026
Merged

Add centralized plugin logging for Python and native plugins#64
thiagoralves merged 2 commits into
developmentfrom
fix/plugin-centralized-logging

Conversation

@thiagoralves

Copy link
Copy Markdown
Contributor

This pull request introduces a centralized logging system for native (C/C++) OpenPLC plugins and updates the Modbus Master Python plugin to use a unified logger interface. The main goals are to ensure that all plugin log messages are routed through the central OpenPLC logging infrastructure and are visible in the Editor, and to improve code clarity and maintainability by standardizing logging usage.

Centralized Logging for Native Plugins:

  • Introduced a new plugin_logger module (plugin_logger.h and plugin_logger.c) that provides a simple, consistent logging interface for native plugins, routing all logs through the central system or falling back to printf as needed. [1] [2]
  • Updated the example native plugin (test_plugin.c) to use the new logger throughout its lifecycle, replacing all direct printf/fprintf calls and improving documentation and code clarity.
  • Modified the example plugin's Makefile to include the new logger source file in the build process.

Python Plugin Logging Improvements:

  • Updated the Modbus Master Python plugin to use the new PluginLogger class, replacing all direct print statements with structured logging calls at appropriate levels (info, warn, error). [1] [2] [3] [4] [5]
  • Passed the logger instance to all slave device threads to ensure consistent logging across components.

These changes improve log visibility, make log messages more consistent and structured, and lay a foundation for future enhancements in plugin observability and debugging.

Most important changes:

Native Plugin Logging Infrastructure:

  • Added new centralized logging utility for native plugins: plugin_logger.h (interface) and plugin_logger.c (implementation), enabling plugins to log info, debug, warning, and error messages through the central OpenPLC system. [1] [2]
  • Refactored the example native plugin (test_plugin.c) to use the new logger throughout, replacing all printf/fprintf usage, improving documentation, and demonstrating proper logger initialization and usage.
  • Updated the example plugin Makefile to compile and link with the new logger source file.

Python Plugin Logging Improvements:

  • Replaced all print statements in the Modbus Master Python plugin with the new PluginLogger interface, using appropriate log levels (info, warn, error). [1] [2] [3] [4]
  • Modified thread and class initialization to pass the logger instance, ensuring all components use the unified logging system.

thiagoralves and others added 2 commits January 6, 2026 15:17
This commit introduces a centralized logging mechanism for both Python
and native (C/C++) plugins to ensure all plugin log messages are routed
through the central logging system and visible in the OpenPLC Editor.

Python plugins:
- Add PluginLogger class in shared/plugin_logger.py
- Update modbus_slave to use PluginLogger (replace ~70 print() calls)
- Update modbus_master to use PluginLogger (replace ~50 print() calls)
- Plugin names are automatically prefixed to messages

Native plugins:
- Add plugin_logger.h/c in plugins/native/
- Update test_plugin.c example to demonstrate proper logging usage
- Update Makefile to compile with plugin_logger

Both implementations:
- Auto-prefix messages with plugin name (e.g., "[MODBUS_SLAVE]")
- Fall back to print/printf if central logging unavailable
- Thread-safe logging support

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Moved plugin_runtime_args_t and logging function pointer typedefs
from plugin_driver.h to a new plugin_types.h header. This allows
native plugins to include only the essential types without pulling
in unnecessary dependencies (plcapp_manager.h, plugin_config.h,
python_plugin_bridge.h).

- Created plugin_types.h with plugin_runtime_args_t and log function types
- Updated plugin_driver.h to include plugin_types.h
- Updated plugin_logger.c to use plugin_types.h instead of plugin_driver.h
- Updated test_plugin.c to use plugin_types.h

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@thiagoralves thiagoralves requested a review from Copilot January 6, 2026 20:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a centralized logging system for OpenPLC plugins, ensuring all log messages from both native (C/C++) and Python plugins are routed through the central logging infrastructure and visible in the Editor. The changes standardize logging interfaces, improve code maintainability, and enhance observability across the plugin ecosystem.

Key changes:

  • Added centralized plugin logger module for native plugins with fallback support
  • Updated Python plugins to use the new PluginLogger class instead of direct print statements
  • Refactored example native plugin to demonstrate proper logger usage

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
plugin_logger.py New Python logger class providing consistent logging interface with automatic plugin name prefixing
__init__.py Exports the new PluginLogger class for use by Python plugins
simple_modbus.py Updated Modbus slave plugin to use PluginLogger throughout, replacing all print statements
modbus_master_plugin.py Migrated Modbus master plugin to use PluginLogger, replacing SafeLoggingAccess and print statements
plugin_logger.h Header defining native plugin logger interface with function pointer types
plugin_logger.c Implementation of native plugin logger with printf fallback
test_plugin.c Updated example plugin demonstrating proper logger initialization and usage
Makefile Modified to compile and link the new logger source file
plugin_types.h New header consolidating common plugin type definitions including logging function pointers
plugin_driver.h Refactored to use plugin_types.h for shared type definitions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +72 to +76
if logger:
logger.warn(
f"Failed to create safe buffer access for coils: "
f"{self.safe_buffer_access.error_msg}"
)

Copilot AI Jan 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logger variable is used without being defined or passed as a parameter to the __init__ method. This will cause a NameError at runtime. The logger should either be passed as a parameter to the class constructor or accessed from a global variable.

Copilot uses AI. Check for mistakes.
Comment on lines +86 to +89
if logger:
logger.error(
f"Safe buffer access not valid: {self.safe_buffer_access.error_msg}"
)

Copilot AI Jan 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logger variable is undefined in this scope. It's not passed to getValues method and will cause a NameError. The logger should be stored as an instance variable in __init__ or passed as a parameter to this method.

Copilot uses AI. Check for mistakes.
Comment on lines +110 to +111
if logger:
logger.error(f"Error reading coil {coil_addr}: {error_msg}")

Copilot AI Jan 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logger variable is undefined in the getValues method scope. This will cause a NameError when the error condition is triggered.

Copilot uses AI. Check for mistakes.
Comment on lines +126 to +129
if logger:
logger.error(
f"Safe buffer access not valid: {self.safe_buffer_access.error_msg}"
)

Copilot AI Jan 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logger variable is undefined in the setValues method scope. It should be stored as an instance variable or passed as a parameter.

Copilot uses AI. Check for mistakes.
Comment on lines +147 to +148
if logger:
logger.error(f"Error setting coil {coil_addr}: {error_msg}")

Copilot AI Jan 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logger variable is undefined in this scope and will cause a NameError.

Copilot uses AI. Check for mistakes.
@thiagoralves thiagoralves merged commit 69a4398 into development Jan 7, 2026
1 check passed
@thiagoralves thiagoralves deleted the fix/plugin-centralized-logging branch January 7, 2026 22:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants