semantic update
This commit is contained in:
@@ -64,24 +64,156 @@ class HelloWorldPlugin(PluginBase):
|
||||
"required": ["name"],
|
||||
}
|
||||
|
||||
async def execute(self, params: Dict[str, Any]):
|
||||
async def execute(self, params: Dict[str, Any], context: Optional[TaskContext] = None):
|
||||
name = params["name"]
|
||||
print(f"Hello, {name}!")
|
||||
if context:
|
||||
context.logger.info(f"Hello, {name}!")
|
||||
else:
|
||||
print(f"Hello, {name}!")
|
||||
```
|
||||
|
||||
## 4. Logging
|
||||
## 4. Logging with TaskContext
|
||||
|
||||
You can use the global logger instance to log messages from your plugin. The logger is available in the `superset_tool.utils.logger` module.
|
||||
Plugins now support TaskContext for structured logging with source attribution. The `context` parameter provides access to a logger that automatically tags logs with the task ID and a source identifier.
|
||||
|
||||
### 4.1. Basic Logging
|
||||
|
||||
Use `context.logger` to log messages with automatic source attribution:
|
||||
|
||||
```python
|
||||
from superset_tool.utils.logger import SupersetLogger
|
||||
from typing import Dict, Any, Optional
|
||||
from ..core.plugin_base import PluginBase
|
||||
from ..core.task_manager.context import TaskContext
|
||||
|
||||
logger = SupersetLogger()
|
||||
|
||||
async def execute(self, params: Dict[str, Any]):
|
||||
logger.info("My plugin is running!")
|
||||
async def execute(self, params: Dict[str, Any], context: Optional[TaskContext] = None):
|
||||
if context:
|
||||
# Use TaskContext logger for structured logging
|
||||
context.logger.info("My plugin is running!")
|
||||
else:
|
||||
# Fallback to global logger for backward compatibility
|
||||
from ..core.logger import logger
|
||||
logger.info("My plugin is running!")
|
||||
```
|
||||
|
||||
### 4.2. Source Attribution
|
||||
|
||||
For better log organization, create sub-loggers for different components:
|
||||
|
||||
```python
|
||||
async def execute(self, params: Dict[str, Any], context: Optional[TaskContext] = None):
|
||||
if context:
|
||||
# Create sub-loggers for different components
|
||||
api_log = context.logger.with_source("api")
|
||||
storage_log = context.logger.with_source("storage")
|
||||
|
||||
api_log.info("Connecting to API...")
|
||||
storage_log.info("Saving file...")
|
||||
else:
|
||||
# Fallback to global logger
|
||||
from ..core.logger import logger
|
||||
logger.info("My plugin is running!")
|
||||
```
|
||||
|
||||
### 4.3. Log Levels
|
||||
|
||||
The logger supports standard log levels. Use them appropriately:
|
||||
|
||||
| Level | Usage |
|
||||
|-------|-------|
|
||||
| `DEBUG` | Detailed diagnostic information (API responses, internal state). Only visible when log level is set to DEBUG. |
|
||||
| `INFO` | General operational messages (start/complete notifications, progress updates). |
|
||||
| `WARNING` | Non-critical issues that don't stop execution (deprecated APIs, retry attempts). |
|
||||
| `ERROR` | Failures that prevent an operation from completing (API errors, validation failures). |
|
||||
|
||||
```python
|
||||
# Good: Use DEBUG for verbose diagnostic info
|
||||
api_log.debug(f"API response: {response.json()}")
|
||||
|
||||
# Good: Use INFO for operational milestones
|
||||
log.info(f"Starting backup for environment: {env}")
|
||||
|
||||
# Good: Use WARNING for recoverable issues
|
||||
log.warning(f"Rate limit hit, retrying in {delay}s")
|
||||
|
||||
# Good: Use ERROR for failures
|
||||
log.error(f"Failed to connect to database: {e}")
|
||||
```
|
||||
|
||||
### 4.4. Progress Logging
|
||||
|
||||
For operations that report progress, use the `progress` method:
|
||||
|
||||
```python
|
||||
async def execute(self, params: Dict[str, Any], context: Optional[TaskContext] = None):
|
||||
if context:
|
||||
total_items = 100
|
||||
for i, item in enumerate(items):
|
||||
# Report progress with percentage
|
||||
percent = (i + 1) / total_items * 100
|
||||
context.logger.progress(f"Processing {item}", percent=percent)
|
||||
else:
|
||||
# Fallback
|
||||
from ..core.logger import logger
|
||||
logger.info("My plugin is running!")
|
||||
```
|
||||
|
||||
### 4.5. Logging with Metadata
|
||||
|
||||
You can include structured metadata with log entries:
|
||||
|
||||
```python
|
||||
async def execute(self, params: Dict[str, Any], context: Optional[TaskContext] = None):
|
||||
if context:
|
||||
context.logger.error(
|
||||
"Operation failed",
|
||||
metadata={"error_code": 500, "details": "Connection timeout"}
|
||||
)
|
||||
else:
|
||||
from ..core.logger import logger
|
||||
logger.error("Operation failed")
|
||||
```
|
||||
|
||||
### 4.6. Common Source Names
|
||||
|
||||
For consistency across plugins, use these standard source names:
|
||||
|
||||
| Source | Usage |
|
||||
|--------|-------|
|
||||
| `superset_api` | Superset REST API calls |
|
||||
| `postgres` | PostgreSQL database operations |
|
||||
| `storage` | File system operations |
|
||||
| `git` | Git operations |
|
||||
| `llm` | LLM API calls |
|
||||
| `screenshot` | Screenshot capture operations |
|
||||
| `migration` | Migration-specific logic |
|
||||
| `backup` | Backup operations |
|
||||
| `debug` | Debug/diagnostic operations |
|
||||
| `search` | Search operations |
|
||||
|
||||
### 4.7. Best Practices
|
||||
|
||||
1. **Always check for context**: Support backward compatibility by checking if `context` is available:
|
||||
```python
|
||||
log = context.logger if context else logger
|
||||
```
|
||||
|
||||
2. **Use source attribution**: Create sub-loggers for different components to make filtering easier in the UI.
|
||||
|
||||
3. **Use appropriate log levels**:
|
||||
- `DEBUG`: Verbose diagnostic info (API responses, internal state)
|
||||
- `INFO`: Operational milestones (start, complete, progress)
|
||||
- `WARNING`: Recoverable issues (rate limits, deprecated APIs)
|
||||
- `ERROR`: Failures that stop an operation
|
||||
|
||||
4. **Log progress for long operations**: Use `progress()` for operations that take time:
|
||||
```python
|
||||
for i, item in enumerate(items):
|
||||
percent = (i + 1) / len(items) * 100
|
||||
log.progress(f"Processing {item}", percent=percent)
|
||||
```
|
||||
|
||||
5. **Keep DEBUG logs verbose, INFO logs concise**: DEBUG logs can include full API responses, while INFO logs should be one-line summaries.
|
||||
|
||||
## 5. Testing
|
||||
|
||||
To test your plugin, simply run the application and navigate to the web UI. Your plugin should appear in the list of available tools.
|
||||
Reference in New Issue
Block a user