Skip to content

Commit

Permalink
Enhance CLI functionality and logging configuration
Browse files Browse the repository at this point in the history
- Added command-line interface (CLI) commands for starting the system, analyzing DAGs, and generating reports.
- Introduced logging configuration with support for console and file logging.
- Updated configuration structure to include monitoring interval and log path.
- Created models for application configuration using Pydantic.
- Updated README with new CLI usage instructions.
  • Loading branch information
pesnik committed Jan 18, 2025
1 parent 8003107 commit 208dccd
Show file tree
Hide file tree
Showing 14 changed files with 243 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ ENV/
*.swp
.DS_Store
config/config.yaml
logs/
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ repos:
rev: v1.6.1
hooks:
- id: mypy
additional_dependencies:
- types-PyYAML

# bandit: Security linting
- repo: https://github.com/PyCQA/bandit
Expand Down
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,27 @@ The application is configured through `config/config.yaml`:

## 📊 Usage

### CLI Interface
### Command-Line Interface (CLI)

DAGnostics provides a CLI for managing the monitoring and reporting system. Use the following commands:

#### Start the System
```bash
poetry run dagnostics start
```

#### Analyze a Specific DAG
```bash
# Generate daily report
dagnostics report daily
poetry run dagnostics analyze <dag-name>
```

# Analyze specific DAG
dagnostics analyze my-dag-name
#### Generate a Report
```bash
# Generate a standard report
poetry run dagnostics report

# Start monitoring server
dagnostics server start
# Generate a daily report
poetry run dagnostics report --daily
```

### Python API
Expand Down
3 changes: 3 additions & 0 deletions config/config.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ llm:
max_tokens: 500

monitoring:
interval: 60
log_path: /var/log/dagnostics

categories:
- system_error
- resource_constraint
Expand Down
48 changes: 48 additions & 0 deletions config/logging.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
version: 1
disable_existing_loggers: False

formatters:
standard:
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
json:
format: '{"time": "%(asctime)s", "name": "%(name)s", "level": "%(levelname)s", "message": "%(message)s"}'

handlers:
console:
class: logging.StreamHandler
level: INFO
formatter: standard
stream: ext://sys.stdout

file:
class: logging.handlers.RotatingFileHandler
level: DEBUG
formatter: standard
filename: logs/app.log
maxBytes: 10485760 # 10 MB
backupCount: 5
encoding: utf8

json_file:
class: logging.handlers.RotatingFileHandler
level: DEBUG
formatter: json
filename: logs/app.json.log
maxBytes: 10485760 # 10 MB
backupCount: 5
encoding: utf8

loggers:
dagnostics:
level: DEBUG
handlers: [console, file]
propagate: False

dagnostics.api:
level: INFO
handlers: [json_file]
propagate: False

root:
level: WARNING
handlers: [console]
1 change: 1 addition & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
[mypy]
exclude = .venv
ignore_missing_imports = false
16 changes: 14 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 8 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
name = "dagnostics"
version = "0.1.0"
description = ""
authors = [
{name = "rhasanm",email = "[email protected]"}
]
authors = [{ name = "rhasanm", email = "[email protected]" }]
readme = "README.md"
requires-python = ">=3.12,<4.0"
dependencies = [
Expand All @@ -17,12 +15,11 @@ dependencies = [
"uvicorn (>=0.34.0,<0.35.0)",
"pydantic (>=2.10.5,<3.0.0)",
"typer (>=0.15.1,<0.16.0)",
"rich (>=13.9.4,<14.0.0)"
"rich (>=13.9.4,<14.0.0)",
]

[tool.poetry]
packages = [{include = "dagnostics", from = "src"}]

packages = [{ include = "dagnostics", from = "src" }]

[tool.poetry.group.dev.dependencies]
invoke = "^2.2.0"
Expand All @@ -33,6 +30,11 @@ isort = "^5.13.2"
flake8 = "^7.1.1"
mypy = "^1.14.1"
pre-commit = "^4.0.1"
types-pyyaml = "^6.0.12.20241230"

[tool.poetry.scripts]
start = "dagnostics.main:main"
dagnostics = "dagnostics.cli.main:cli"

[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
Expand Down
38 changes: 38 additions & 0 deletions src/dagnostics/cli/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import typer

from dagnostics.core.config import load_config
from dagnostics.monitoring.collector import start_monitoring
from dagnostics.reporting.generator import setup_reporting

app = typer.Typer()


@app.command()
def start():
"""Start the DAGnostics monitoring and reporting system."""
config = load_config()
typer.echo("Starting DAGnostics...")
start_monitoring(config)
setup_reporting(config)


@app.command()
def analyze(dag_name: str):
"""Analyze a specific DAG."""
# config = load_config()
typer.echo(f"Analyzing DAG: {dag_name}")


@app.command()
def report(daily: bool = False):
"""Generate a report."""
# config = load_config()
if daily:
typer.echo("Generating daily report...")
else:
typer.echo("Generating report...")


def cli():
"""Entry point for the CLI."""
app()
16 changes: 16 additions & 0 deletions src/dagnostics/core/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from pathlib import Path

import yaml

from dagnostics.core.models import AppConfig


def load_config() -> AppConfig:
"""Load and parse the application configuration."""
config_path = Path("config/config.yaml")
if config_path.exists():
with open(config_path, "r") as f:
raw_config = yaml.safe_load(f)
return AppConfig(**raw_config)
else:
raise FileNotFoundError("Configuration file not found: config/config.yaml")
18 changes: 18 additions & 0 deletions src/dagnostics/core/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from pydantic import BaseModel, Field


class MonitoringConfig(BaseModel):
interval: int = Field(gt=0, description="Monitoring interval in seconds")
log_path: str = Field(..., description="Path to store logs")


class ReportingConfig(BaseModel):
format: str = Field(default="markdown", description="Report format")
output_dir: str = Field(
default="reports", description="Output directory for reports"
)


class AppConfig(BaseModel):
monitoring: MonitoringConfig
reporting: ReportingConfig
49 changes: 49 additions & 0 deletions src/dagnostics/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import logging.config
from pathlib import Path

import yaml

from dagnostics.cli.main import cli
from dagnostics.core.config import load_config
from dagnostics.monitoring.collector import start_monitoring
from dagnostics.reporting.generator import setup_reporting


def setup_logging():
"""Load logging configuration from logging.yaml and ensure logs directory exists."""
logging_config_path = Path("config/logging.yaml")
if logging_config_path.exists():
with open(logging_config_path, "r") as f:
config = yaml.safe_load(f)

logs_dir = Path("logs")
logs_dir.mkdir(exist_ok=True)

logging.config.dictConfig(config)
else:
logging.basicConfig(level=logging.INFO)
logging.warning(
"Logging configuration file not found. Using default logging settings."
)


def main():
"""Main entry point for the DAGnostics application."""
setup_logging()
logger = logging.getLogger(__name__)
logger.info("Starting DAGnostics...")

config = load_config()
logger.info("Configuration loaded successfully.")

start_monitoring(config)
logger.info("Monitoring started.")

setup_reporting(config)
logger.info("Reporting setup complete.")

cli()


if __name__ == "__main__":
main()
14 changes: 14 additions & 0 deletions src/dagnostics/monitoring/collector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import logging

from dagnostics.core.config import AppConfig

logger = logging.getLogger(__name__)


def start_monitoring(config: AppConfig):
"""Start monitoring DAG failures."""
logger.info("Starting monitoring system...")
logger.info(f"Monitoring interval: {config.monitoring.interval}")
logger.info(f"Log path: {config.monitoring.log_path}")

logger.info("Monitoring system started.")
14 changes: 14 additions & 0 deletions src/dagnostics/reporting/generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import logging

from dagnostics.core.config import AppConfig

logger = logging.getLogger(__name__)


def setup_reporting(config: AppConfig):
"""Set up the reporting system."""
logger.info("Setting up reporting system...")
logger.info(f"Report format: {config.reporting.format}")
logger.info(f"Output directory: {config.reporting.output_dir}")

logger.info("Reporting system setup complete.")

0 comments on commit 208dccd

Please sign in to comment.