docs(diagrams): add component-level architecture diagrams

- DLP Endpoint Monitoring diagram with data flows
- Browser Domains Monitoring with categorization
- WebUI Russian Localization patches structure
- DLP Events Aggregation pipeline
- Prometheus Metrics Exporter architecture
- System overview with all components and connections

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
igor04091968
2026-05-05 01:49:55 +03:00
co-authored by Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent db1998c428
commit d8320799e6
6 changed files with 1992 additions and 0 deletions
+305
View File
@@ -0,0 +1,305 @@
# Browser Domains Monitoring - Компонентная диаграмма
## Обзор
Мониторинг посещаемых доменов в браузерах с категоризацией и проверкой DLP правил.
## Архитектура
```mermaid
graph TB
subgraph "Browser Domains Collector"
A[Main Loop]
B[Window Detection]
C[URL Extraction]
D[Domain Parsing]
E[Web Categorization]
F[DLP Rule Check]
G[Incident Handler]
H[Event Logger]
I[Screenshot Capture]
end
subgraph "External Dependencies"
J[Windows API]
K[Web Category API]
L[DLP Policy]
M[ActivityWatch API]
N[Custom Category Rules]
end
A --> B
B --> C
C --> D
D --> E
D --> F
E --> F
F --> G
G --> H
G --> I
B --> J
C --> J
E --> K
F --> L
H --> M
E --> N
F --> N
style B fill:#ff6b6b
style E fill:#4ecdc4
style F fill:#4ecdc4
style G fill:#ffe66d
```
## Потоки данных
### Domain Detection Flow
```mermaid
sequenceDiagram
participant User
participant Browser as Browser Window
participant Windows as Windows API
participant Collector as Browser Collector
participant Parser as Domain Parser
participant Category as Category API
participant DLP as DLP Engine
participant AW as ActivityWatch
User->>Browser: Navigate to website
Browser->>Windows: Window title change
Windows->>Collector: Window event
Collector->>Collector: Check if browser
Collector->>Collector: Extract URL from window
Collector->>Parser: Parse domain
Parser->>Collector: Return domain
Collector->>Category: Get web category
Category->>Collector: Return category
Collector->>DLP: Check DLP rules
alt Violation
DLP->>Collector: Trigger incident
Collector->>Collector: Capture screenshot
Collector->>AW: Send DLP incident
else Normal
Collector->>AW: Send browsing event
end
```
### Domain Categorization Flow
```mermaid
graph LR
A[URL] --> B[Extract Domain]
B --> C{Custom Rules?}
C -->|Yes| D[Apply Custom Category]
C -->|No| E[Call Category API]
D --> F[Return Category]
E --> F
F --> G[Cache Result]
G --> H[Use in DLP Check]
```
## Ключевые функции
### Обнаружение и извлечение
- `browser_domains_native_collector_get_foregroundwindowcontext()` - контекст активного окна
- `browser_domains_native_collector_get_browserurlfromwindow()` - извлечение URL из окна
- `browser_domains_native_collector_get_hostfromurl()` - извлечение домена из URL
- `browser_domains_native_collector_get_rootdomain()` - получение корневого домена
### Категоризация
- `browser_domains_native_collector_get_webcategory()` - определение категории сайта
- `browser_domains_native_collector_load_customcategoryrules()` - загрузка кастомных правил
- `browser_domains_native_collector_test_domainlistmatch()` - проверка по спискам доменов
### DLP проверка
- `browser_domains_native_collector_get_dlpdecision()` - решение DLP
- `browser_domains_native_collector_test_dlprulematch()` - проверка DLP правила
- `browser_domains_native_collector_test_dlpruletimewindow()` - проверка временного окна
- `browser_domains_native_collector_should_emitincident()` - решение о создании инцидента
### Логирование
- `browser_domains_native_collector_write_collectorlog()` - лог коллектора
- `browser_domains_native_collector_write_dlpincidentlog()` - лог DLP инцидента
- `browser_domains_native_collector_send_heartbeat()` - heartbeat
- `browser_domains_native_collector_send_categoryheartbeat()` - heartbeat категорий
### Утилиты
- `browser_domains_native_collector_convertto_normalizedurl()` - нормализация URL
- `browser_domains_native_collector_test_domainmatch()` - проверка совпадения домена
## Конфигурация
### Custom Category Rules
```json
{
"custom_categories": {
"social_media": [
"*.facebook.com",
"*.twitter.com",
"*.instagram.com"
],
"news": [
"*.news.com",
"*.media.com"
],
"blocked": [
"*.malware.com",
"*.phishing.com"
]
}
}
```
### DLP Domain Rules
```json
{
"domain_rules": [
{
"pattern": "*gambling*",
"category": "gambling",
"action": "alert",
"severity": "medium"
},
{
"pattern": "*adult*",
"category": "adult",
"action": "block",
"severity": "high"
}
]
}
```
### Deployment Config
```json
{
"aw_server_url": "http://aw-server:5600",
"bucket_prefix": "aw-watcher-browser-domains",
"category_api_enabled": true,
"custom_categories_enabled": true,
"screenshot_on_incident": true,
"heartbeat_interval": 60
}
```
## События
### Browsing Event
```json
{
"timestamp": "2024-01-01T12:00:00Z",
"type": "browsing",
"data": {
"url": "https://www.example.com/page",
"domain": "example.com",
"root_domain": "example.com",
"category": "technology",
"browser": "chrome.exe",
"title": "Example Page Title",
"user": "user1",
"host": "WORKSTATION01"
}
}
```
### DLP Incident Event
```json
{
"timestamp": "2024-01-01T12:00:00Z",
"type": "dlp_incident",
"source": "browser_domain",
"rule_id": "blocked_domains",
"severity": "high",
"data": {
"url": "https://blocked.com",
"domain": "blocked.com",
"category": "malicious",
"user": "user1",
"host": "WORKSTATION01",
"screenshot": "path/to/screenshot.png"
}
}
```
### Category Heartbeat
```json
{
"timestamp": "2024-01-01T12:00:00Z",
"type": "category_heartbeat",
"data": {
"domains_seen": 150,
"categories": {
"technology": 50,
"news": 30,
"social_media": 40,
"other": 30
}
}
}
```
## Поддерживаемые браузеры
- Google Chrome
- Mozilla Firefox
- Microsoft Edge
- Opera
- Яндекс.Браузер
## Зависимости
### Windows API
- Window enumeration
- Window title extraction
- Process information
### Внешние сервисы
- Web categorization API (опционально)
- ActivityWatch HTTP API
## Алгоритм категоризации
```mermaid
graph TD
A[Domain extracted] --> B{Custom rule match?}
B -->|Yes| C[Return custom category]
B -->|No| D{Cache hit?}
D -->|Yes| E[Return cached category]
D -->|No| F[Call category API]
F --> G{API success?}
G -->|Yes| H[Cache result]
G -->|No| I[Return 'uncategorized']
H --> J[Return category]
I --> J
```
## Мониторинг
### Метрики
- Количество уникальных доменов
- Распределение по категориям
- Частота DLP инцидентов
- Кэш hit rate для категорий
### Алерты
- Коллектор не активен > 5 минут
- Высокий процент blocked категорий
- Ошибки category API
- Много неизвестных категорий
## Производительность
### Оптимизации
- Кэширование категорий доменов
- Batch запросы к category API
- Debouncing быстрых переходов
- Асинхронная отправка событий
### Настройки производительности
```json
{
"cache_ttl": 86400,
"batch_size": 50,
"debounce_ms": 1000,
"max_events_per_minute": 100
}
```
+375
View File
@@ -0,0 +1,375 @@
# DLP Events Aggregation - Компонентная диаграмма
## Обзор
Система агрегации DLP событий из ActivityWatch buckets в PostgreSQL для аналитики и отчетности.
## Архитектура
```mermaid
graph TB
subgraph "Aggregation Pipeline"
A[Main Orchestrator]
B[Bucket Discovery]
C[Event Fetcher]
D[Event Parser]
E[Normalizer]
F[PostgreSQL Writer]
G[State Manager]
end
subgraph "Data Sources"
H[ActivityWatch API]
I[SQLite Buckets]
J[PostgreSQL Database]
end
subgraph "Output"
K[Aggregated Events]
L[Statistics]
M[Reports]
end
A --> B
A --> C
A --> G
B --> H
C --> H
C --> I
D --> C
E --> D
F --> E
F --> J
G --> J
F --> K
F --> L
F --> M
style A fill:#4ecdc4
style F fill:#ff6b6b
style G fill:#ffe66d
```
## Потоки данных
### Aggregation Flow
```mermaid
sequenceDiagram
participant Orchestrator as Main Orchestrator
participant State as State Manager
participant AW as ActivityWatch API
participant Fetcher as Event Fetcher
participant Parser as Event Parser
participant PG as PostgreSQL
Orchestrator->>State: Load last sync state
State->>Orchestrator: Return last timestamp
Orchestrator->>AW: List buckets
AW->>Orchestrator: Return bucket list
loop For each DLP bucket
Orchestrator->>AW: Get events since last sync
AW->>Fetcher: Return events
Fetcher->>Parser: Parse event structure
Parser->>Parser: Extract DLP data
Parser->>Orchestrator: Return parsed events
Orchestrator->>PG: Insert batch of events
PG->>Orchestrator: Confirm insert
end
Orchestrator->>State: Save new sync state
State->>PG: Persist state
```
### Event Processing Pipeline
```mermaid
graph LR
A[Raw Event] --> B[Parse JSON]
B --> C[Extract DLP Fields]
C --> D[Normalize Timestamp]
D --> E[Enrich with User/Host]
E --> F[Validate Data]
F --> G[Batch Prepare]
G --> H[PostgreSQL Insert]
```
## Ключевые функции
### Оркестрация
- `aggregate_dlp_events_main()` - главная функция агрегации
- `aggregate_dlp_events_list_buckets()` - получение списка buckets
- `aggregate_dlp_events_get_start_time()` - определение начала периода
### Получение событий
- `aggregate_dlp_events_fetch_bucket_events()` - получение событий из bucket
- `aggregate_dlp_events_bucket_stream_type()` - определение типа потока
- `aggregate_dlp_events_aw_get_json()` - HTTP запрос к AW API
### Парсинг
- `aggregate_dlp_events_awevent()` - парсинг события AW
- `aggregate_dlp_events_parse_timestamp()` - парсинг timestamp
- `aggregate_dlp_events_parse_prefixes()` - парсинг префиксов bucket
- `aggregate_dlp_events_event_row()` - формирование строки события
### Нормализация
- `aggregate_dlp_events_normalize_base_url()` - нормализация URL AW API
- `aggregate_dlp_events_format_aw_timestamp()` - форматирование timestamp
- `aggregate_dlp_events_bool_as_int()` - конвертация boolean в int
- `aggregate_dlp_events_first_string()` - получение первой строки
### Батчинг
- `aggregate_dlp_events_bucket()` - обработка bucket
- `aggregate_dlp_events_build_events_path()` - построение пути к событиям
- `aggregate_dlp_events_build_parser()` - создание парсера
### Соединения
- `aggregate_dlp_events_connect_sqlite()` - соединение с SQLite
- `aggregate_dlp_events_psycopgconnection()` - соединение с PostgreSQL
- `aggregate_dlp_events_psycopgconnection_cursor()` - курсор PostgreSQL
- `aggregate_dlp_events_psycopgconnection_commit()` - коммит транзакции
### Запись
- `aggregate_dlp_events_insert_events()` - вставка событий
- `aggregate_dlp_events_insert_postgres_events()` - вставка в PostgreSQL
- `aggregate_dlp_events_select_buckets()` - выборка buckets
- `aggregate_dlp_events_ensure_schema()` - обеспечение схемы БД
### Управление состоянием
- `aggregate_dlp_events_load_state()` - загрузка состояния
- `aggregate_dlp_events_save_state()` - сохранение состояния
- `aggregate_dlp_events_event_key()` - ключ события
### Утилиты
- `aggregate_dlp_events_utc_now()` - текущее UTC время
- `aggregate_dlp_events_ensure_postgres_schema()` - схема PostgreSQL
## Схема базы данных
### Таблица dlp_events
```sql
CREATE TABLE dlp_events (
id SERIAL PRIMARY KEY,
timestamp TIMESTAMP NOT NULL,
event_type VARCHAR(50) NOT NULL,
source VARCHAR(50) NOT NULL,
rule_id VARCHAR(100),
severity VARCHAR(20),
user_id VARCHAR(100),
host_id VARCHAR(100),
data JSONB,
created_at TIMESTAMP DEFAULT NOW(),
INDEX idx_timestamp (timestamp),
INDEX idx_user (user_id),
INDEX idx_host (host_id),
INDEX idx_severity (severity),
INDEX idx_type (event_type)
);
```
### Таблица aggregation_state
```sql
CREATE TABLE aggregation_state (
id SERIAL PRIMARY KEY,
bucket_id VARCHAR(255) UNIQUE NOT NULL,
last_synced_timestamp TIMESTAMP,
last_synced_at TIMESTAMP DEFAULT NOW(),
events_processed INTEGER DEFAULT 0
);
```
### Таблица dlp_statistics
```sql
CREATE TABLE dlp_statistics (
id SERIAL PRIMARY KEY,
date DATE NOT NULL,
user_id VARCHAR(100),
host_id VARCHAR(100),
event_type VARCHAR(50),
severity VARCHAR(20),
incident_count INTEGER DEFAULT 0,
UNIQUE(date, user_id, host_id, event_type, severity)
);
```
## Конфигурация
### Config File
```json
{
"aw_base_url": "http://aw-server:5600",
"postgres_url": "postgresql://user:pass@localhost:5432/activitywatch",
"batch_size": 1000,
"sync_interval_minutes": 5,
"bucket_prefixes": [
"aw-watcher-dlp-endpoint",
"aw-watcher-browser-domains",
"aw-watcher-email-outbound"
],
"retention_days": 90
}
```
### Environment Variables
```bash
AW_BASE_URL=http://aw-server:5600
POSTGRES_URL=postgresql://aw:password@localhost:5432/activitywatch
BATCH_SIZE=1000
SYNC_INTERVAL=300
LOG_LEVEL=INFO
```
## События
### Input Event (from ActivityWatch)
```json
{
"id": "event_id",
"timestamp": "2024-01-01T12:00:00Z",
"duration": 60.0,
"data": {
"type": "dlp_incident",
"source": "clipboard",
"rule_id": "credit_card_pattern",
"severity": "high",
"user": "user1",
"host": "WORKSTATION01",
"matched_text": "****-****-****-1234"
}
}
```
### Output Event (in PostgreSQL)
```sql
INSERT INTO dlp_events (
timestamp, event_type, source, rule_id,
severity, user_id, host_id, data
) VALUES (
'2024-01-01 12:00:00',
'dlp_incident',
'clipboard',
'credit_card_pattern',
'high',
'user1',
'WORKSTATION01',
'{"matched_text": "****-****-****-1234"}'::jsonb
);
```
## Производительность
### Оптимизации
- Batch вставки (по 1000 событий)
- Connection pooling к PostgreSQL
- Асинхронная обработка
- Индексы на частых запросах
### Метрики производительности
```python
performance_metrics = {
"events_per_second": 100,
"batch_insert_time_ms": 50,
"api_latency_ms": 20,
"postgres_write_latency_ms": 30
}
```
### Мониторинг
- Время обработки batch
- Размер очереди событий
- Ошибки соединения с PostgreSQL
- Latency API запросов
## Обработка ошибок
### Retry Strategy
```python
retry_config = {
"max_retries": 3,
"backoff_seconds": [1, 5, 15],
"retry_on": [
"ConnectionError",
"TimeoutError",
"DatabaseError"
]
}
```
### Dead Letter Queue
```sql
CREATE TABLE dlp_events_failed (
id SERIAL PRIMARY KEY,
raw_event JSONB,
error_message TEXT,
failed_at TIMESTAMP DEFAULT NOW(),
retry_count INTEGER DEFAULT 0
);
```
## Планирование
### Cron Job
```cron
*/5 * * * * /usr/bin/python3 /path/to/aggregate_dlp_events.py
```
### Systemd Service
```ini
[Unit]
Description=ActivityWatch DLP Aggregation
After=network.target
[Service]
Type=simple
User=aw-aggregator
ExecStart=/usr/bin/python3 /path/to/aggregate_dlp_events.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
## Отчеты
### Daily Report
```sql
SELECT
date,
event_type,
severity,
COUNT(*) as incident_count
FROM dlp_events
WHERE date >= CURRENT_DATE - INTERVAL '7 days'
GROUP BY date, event_type, severity
ORDER BY date DESC, incident_count DESC;
```
### User Summary
```sql
SELECT
user_id,
COUNT(*) as total_incidents,
COUNT(CASE WHEN severity = 'high' THEN 1 END) as high_severity,
COUNT(CASE WHEN severity = 'medium' THEN 1 END) as medium_severity
FROM dlp_events
WHERE timestamp >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY user_id
ORDER BY total_incidents DESC;
```
## Валидация данных
### Checks
- Timestamp в допустимом диапазоне
- Обязательные поля заполнены
- Severity в списке допустимых значений
- User/Host существуют в справочниках
### Data Quality
```python
validation_rules = {
"timestamp": "required, past_date",
"event_type": "required, in_list",
"severity": "required, in_list",
"user_id": "required, max_length=100",
"host_id": "required, max_length=100"
}
```
+264
View File
@@ -0,0 +1,264 @@
# DLP Endpoint Monitoring - Компонентная диаграмма
## Обзор
Мониторинг конечных точек для обнаружения утечек данных через clipboard, печать и USB.
## Архитектура
```mermaid
graph TB
subgraph "DLP Endpoint Collector"
A[Main Loop]
B[Load DLP Policy]
C[Deployment Config]
D[Clipboard Monitor]
E[Print Monitor]
F[USB Monitor]
G[Rule Engine]
H[Enforcement Actions]
I[Event Logging]
J[Screenshot Capture]
end
subgraph "External Dependencies"
K[ActivityWatch API]
L[DLP Policy JSON]
M[Windows API]
N[File System]
end
A --> B
A --> C
B --> G
C --> A
D --> G
E --> G
F --> G
G --> H
G --> I
G --> J
H --> M
I --> N
J --> N
I --> K
A --> K
B --> L
C --> L
style D fill:#ff6b6b
style E fill:#ff6b6b
style F fill:#ff6b6b
style G fill:#4ecdc4
style H fill:#ffe66d
```
## Потоки данных
### Clipboard Monitoring Flow
```mermaid
sequenceDiagram
participant User
participant Clipboard as Clipboard API
participant Collector as DLP Collector
participant RuleEngine as Rule Engine
participant AW as ActivityWatch
participant FS as File System
User->>Clipboard: Copy data
Clipboard->>Collector: Clipboard change event
Collector->>RuleEngine: Evaluate against rules
RuleEngine->>RuleEngine: Check patterns
alt Pattern Match
RuleEngine->>Collector: Trigger incident
Collector->>FS: Capture screenshot
Collector->>Collector: Apply enforcement
Collector->>AW: Send DLP incident
else No Match
RuleEngine->>Collector: Allow
end
```
### Print Monitoring Flow
```mermaid
sequenceDiagram
participant App as Application
participant PrintSpooler as Print Spooler
participant Collector as DLP Collector
participant RuleEngine as Rule Engine
participant AW as ActivityWatch
App->>PrintSpooler: Print job
PrintSpooler->>Collector: Print service event
Collector->>Collector: Extract document info
Collector->>RuleEngine: Evaluate printer rules
alt Violation
RuleEngine->>Collector: Block print job
Collector->>PrintSpooler: Cancel job
Collector->>AW: Log incident
else Allowed
Collector->>AW: Log print activity
end
```
### USB Monitoring Flow
```mermaid
sequenceDiagram
participant User
participant USB as USB Device
participant Windows as Windows API
participant Collector as DLP Collector
participant RuleEngine as Rule Engine
participant AW as ActivityWatch
User->>USB: Insert USB drive
USB->>Windows: Device connect
Windows->>Collector: USB device event
Collector->>RuleEngine: Check USB rules
alt Write Blocked
RuleEngine->>Collector: Block write
Collector->>Windows: Prevent write
Collector->>AW: Log blocked attempt
else Write Allowed
Collector->>AW: Log file copy
end
```
## Ключевые функции
### Основные функции
- `dlp_endpoint_signals_collector_main()` - главный цикл коллектора
- `dlp_endpoint_signals_collector_load_dlppolicy()` - загрузка DLP правил
- `dlp_endpoint_signals_collector_get_deploymentconfig()` - чтение конфигурации
### Мониторинг
- `dlp_endpoint_signals_collector_evaluate_clipboardrules()` - проверка clipboard
- `dlp_endpoint_signals_collector_evaluate_printrules()` - проверка печати
- `dlp_endpoint_signals_collector_evaluate_usbrules()` - проверка USB
### Принудительные действия
- `dlp_endpoint_signals_collector_invoke_clipboardenforcement()` - блокировка clipboard
- `dlp_endpoint_signals_collector_invoke_printjobenforcement()` - блокировка печати
- `dlp_endpoint_signals_collector_invoke_usbwriteblockenforcement()` - блокировка USB
### Логирование
- `dlp_endpoint_signals_collector_write_endpointlog()` - запись логов коллектора
- `dlp_endpoint_signals_collector_send_dlpincidentheartbeat()` - heartbeat инцидентов
- `dlp_endpoint_signals_collector_capture_incidentscreenshot()` - захват скриншота
## Конфигурация
### DLP Policy Structure
```json
{
"clipboard_rules": [
{
"pattern": "\\b\\d{4}-\\d{4}-\\d{4}-\\d{4}\\b",
"description": "Credit card numbers",
"severity": "high",
"action": "block"
}
],
"print_rules": [
{
"printer_match": "*",
"document_keywords": ["confidential", "secret"],
"action": "block"
}
],
"usb_rules": [
{
"device_id": "*",
"action": "block_write"
}
]
}
```
### Deployment Config
```json
{
"aw_server_url": "http://aw-server:5600",
"bucket_prefix": "aw-watcher-dlp-endpoint",
"heartbeat_interval": 60,
"screenshot_on_incident": true,
"enforcement_enabled": true
}
```
## События
### DLP Incident Event
```json
{
"timestamp": "2024-01-01T12:00:00Z",
"type": "dlp_incident",
"source": "clipboard",
"rule_id": "credit_card_pattern",
"severity": "high",
"data": {
"matched_text": "****-****-****-1234",
"user": "user1",
"host": "WORKSTATION01",
"application": "chrome.exe",
"screenshot": "path/to/screenshot.png"
}
}
```
### Heartbeat Event
```json
{
"timestamp": "2024-01-01T12:00:00Z",
"type": "heartbeat",
"status": "running",
"incidents_count": 5,
"last_incident": "2024-01-01T11:55:00Z"
}
```
## Зависимости
### Windows API
- Clipboard API
- Print Spooler API
- USB Device Notification API
- Process API
### External Services
- ActivityWatch HTTP API
- File system (для скриншотов и логов)
## Развертывание
### Требования
- Windows 10/11
- PowerShell 5.1+
- ActivityWatch installed
- Административские права (для enforcement)
### Установка
```powershell
# Копирование коллектора
Copy-Item dlp-endpoint-signals-collector.ps1 C:\ProgramData\AWatch-rus\
# Настройка scheduled task
Register-ScheduledTask -TaskName "DLP Endpoint Collector" -Trigger $trigger -Action $action
```
## Мониторинг
### Метрики
- Количество инцидентов по типам (clipboard/print/USB)
- Частота срабатываний правил
- Успешность enforcement действий
- Heartbeat статус
### Алерты
- Коллектор не отправляет heartbeat > 5 минут
- Высокая частота DLP инцидентов
- Ошибки enforcement действий
+338
View File
@@ -0,0 +1,338 @@
# ActivityWatch-Russian - Обзор компонентов и связей
## Полная архитектура системы
```mermaid
graph TB
subgraph "Windows Clients"
subgraph "Workstation 1"
W1A[DLP Endpoint Collector]
W1B[Browser Domains Collector]
W1C[Email Outbound Collector]
W1D[Worktime Session Collector]
end
subgraph "Workstation 2"
W2A[DLP Endpoint Collector]
W2B[Browser Domains Collector]
W2C[Email Outbound Collector]
end
end
subgraph "Linux Server"
S1[ActivityWatch Server]
S2[PostgreSQL Database]
S3[WebUI with RU Patches]
end
subgraph "Integration Layer"
I1[pfSense Poller]
I2[DLP Aggregation Scripts]
I3[Prometheus Exporter]
end
subgraph "Monitoring Stack"
M1[Prometheus]
M2[Grafana]
M3[SQL Exporter]
end
subgraph "External Systems"
E1[pfSense Firewall]
E2[Domain Controller]
end
W1A -->|Events| S1
W1B -->|Events| S1
W1C -->|Events| S1
W1D -->|Events| S1
W2A -->|Events| S1
W2B -->|Events| S1
W2C -->|Events| S1
S1 -->|Store| S2
S1 -->|Serve| S3
I1 -->|Logs| E1
I1 -->|Events| S1
I2 -->|Read/Write| S2
I2 -->|Read| S1
I3 -->|Metrics| S1
I3 -->|Scrape| M1
M1 -->|Query| I3
M2 -->|Query| M1
M2 -->|Query| S2
M3 -->|Query| S2
E2 -->|Deploy| W1A
E2 -->|Deploy| W1B
E2 -->|Deploy| W1C
E2 -->|Deploy| W2A
E2 -->|Deploy| W2B
E2 -->|Deploy| W2C
style S1 fill:#4ecdc4
style S2 fill:#ff6b6b
style M1 fill:#ffe66d
style M2 fill:#95e1d3
```
## Матрица связей компонентов
| Компонент | Тип | Подключается к | Протокол | Назначение |
|-----------|-----|----------------|-----------|------------|
| DLP Endpoint Collector | Windows Client | AW Server | HTTP API | Отправка DLP событий |
| Browser Domains Collector | Windows Client | AW Server | HTTP API | Отправка браузерных событий |
| Email Outbound Collector | Windows Client | AW Server | HTTP API | Отправка email событий |
| Worktime Session Collector | Windows Client | AW Server | HTTP API | Отправка сессий |
| ActivityWatch Server | Server | PostgreSQL | TCP | Хранение данных |
| ActivityWatch Server | Server | WebUI | HTTP | Отдача интерфейса |
| pfSense Poller | Integration | pfSense | HTTP API | Сбор логов firewall |
| pfSense Poller | Integration | AW Server | HTTP API | Отправка событий |
| DLP Aggregation | Integration | PostgreSQL | TCP | Обработка событий |
| DLP Aggregation | Integration | AW Server | HTTP API | Чтение событий |
| Prometheus Exporter | Integration | AW Server | HTTP API | Сбор метрик |
| Prometheus Exporter | Integration | Prometheus | HTTP | Отдача метрик |
| Prometheus | Monitoring | Exporter | HTTP | Scraping метрик |
| Grafana | Monitoring | Prometheus | HTTP | Запросы метрик |
| Grafana | Monitoring | PostgreSQL | TCP | Прямые запросы |
| SQL Exporter | Monitoring | PostgreSQL | TCP | SQL запросы |
## Потоки данных по уровням
### Уровень 1: Сбор данных (Windows)
```
┌─────────────────────────────────────────────────────────────┐
│ Windows Clients │
├─────────────────────────────────────────────────────────────┤
│ │
│ Workstation 1 Workstation 2 Workstation N │
│ ┌─────────────┐ ┌─────────────┐ ┌──────────┐ │
│ │ DLP Collector│ │ DLP Collector│ │ DLP Coll.│ │
│ │ Browser Coll.│ │ Browser Coll.│ │ Browser │ │
│ │ Email Coll. │ │ Email Coll. │ │ Email │ │
│ │ Worktime │ │ │ │ │ │
│ └──────┬──────┘ └──────┬──────┘ └────┬─────┘ │
│ │ │ │ │
│ └──────────────────────┼───────────────────┘ │
│ │ │
└────────────────────────────────┼────────────────────────────┘
│ HTTP API
```
### Уровень 2: Хранение и обработка (Linux)
```
┌─────────────────────────────────────────────────────────────┐
│ Linux Server Layer │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────┐ │
│ │ AW Server │◄────── Events │
│ │ (Rust) │ │
│ └───────┬───────┘ │
│ │ Store │
│ ▼ │
│ ┌───────────────┐ │
│ │ PostgreSQL │ │
│ └───────┬───────┘ │
│ │ │
└────────────────────────────┼───────────────────────────────┘
```
### Уровень 3: Интеграции
```
┌─────────────────────────────────────────────────────────────┐
│ Integration Layer │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ pfSense │ │ DLP Aggreg. │ │ Prometheus │ │
│ │ Poller │ │ Scripts │ │ Exporter │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ pfSense FW │ │ PostgreSQL │ │ AW Server │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```
### Уровень 4: Визуализация
```
┌─────────────────────────────────────────────────────────────┐
│ Monitoring & Visualization │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Prometheus │◄───┤ Exporter │ │ Grafana │ │
│ │ │ │ │ │ │ │
│ └──────┬───────┘ └──────────────┘ └──────┬───────┘ │
│ │ │ │
│ │ Query │ Query │
│ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Grafana │ │ PostgreSQL │ │
│ │ Dashboards │ │ │ │
│ └──────────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```
## Сценарии использования
### Сценарий 1: DLP инцидент
```
User copies sensitive data
DLP Endpoint Collector detects
Evaluates against rules
Creates incident event
Sends to AW Server
Stored in PostgreSQL
Aggregated by scripts
Visible in Grafana DLP Dashboard
```
### Сценарий 2: Мониторинг браузера
```
User visits website
Browser Domains Collector detects
Extracts domain
Categorizes website
Checks DLP rules
Sends event to AW Server
Visible in WebUI Dashboard
```
### Сценарий 3: Метрики
```
Prometheus scrapes Exporter
Exporter queries AW API
Collects metrics
Returns in Prometheus format
Prometheus stores metrics
Grafana visualizes in dashboards
```
## Зависимости развертывания
### Минимальная конфигурация
```
1 Linux Server:
- ActivityWatch Server
- PostgreSQL
- WebUI with patches
1+ Windows Workstations:
- DLP Endpoint Collector
- Browser Domains Collector
- Email Outbound Collector
```
### Полная конфигурация
```
1 Linux Server:
- ActivityWatch Server
- PostgreSQL
- WebUI with patches
- DLP Aggregation Scripts
- Prometheus Exporter
1+ Windows Workstations:
- DLP Endpoint Collector
- Browser Domains Collector
- Email Outbound Collector
- Worktime Session Collector
1 pfSense Firewall:
- pfSense Poller
1 Monitoring Server:
- Prometheus
- Grafana
- SQL Exporter
```
## Порты и протоколы
| Компонент | Порт | Протокол | Направление |
|-----------|------|----------|-------------|
| ActivityWatch API | 5600 | HTTP | Inbound |
| ActivityWatch WebSocket | 5666 | WebSocket | Inbound |
| PostgreSQL | 5432 | TCP | Inbound |
| Prometheus | 9090 | HTTP | Inbound |
| Grafana | 3000 | HTTP | Inbound |
| Prometheus Exporter | 9398 | HTTP | Inbound |
| pfSense API | 443 | HTTPS | Outbound |
## Резервное копирование
### PostgreSQL Backup
```bash
# Daily backup
pg_dump activitywatch > backup_$(date +%Y%m%d).sql
# Restore
psql activitywatch < backup_20240101.sql
```
### AW Server Backup
```bash
# Backup SQLite databases (if used)
cp /var/lib/activitywatch/*.db /backup/
# Backup configuration
cp /etc/activitywatch/config.toml /backup/
```
## Масштабирование
### Горизонтальное масштабирование
- Добавление Windows workstation не требует изменений сервера
- Каждый workstation автономно отправляет события
- Server обрабатывает события от множества клиентов
### Вертикальное масштабирование
- Увеличение ресурсов PostgreSQL для больших объемов данных
- Разделение AW Server и PostgreSQL на разные машины
- Добавление реплик PostgreSQL для высокой доступности
## Мониторинг системы
### Ключевые метрики
- Количество активных хостов
- Скорость поступления событий
- Размер базы данных
- Latency обработки событий
- Статус коллекторов
### Алерты
- Коллектор неактивен > 5 минут
- Высокий процент DLP инцидентов
- PostgreSQL connection pool exhausted
- Диск > 80% заполнен
- AW Server недоступен
+373
View File
@@ -0,0 +1,373 @@
# Prometheus Metrics Exporter - Компонентная диаграмма
## Обзор
Экспорт метрик ActivityWatch в формате Prometheus для мониторинга и визуализации в Grafana.
## Архитектура
```mermaid
graph TB
subgraph "Prometheus Exporter"
A[HTTP Server]
B[Metrics Collector]
C[Bucket Fetcher]
D[Event Counter]
E[Host Tracker]
F[Metrics Formatter]
G[Registry]
end
subgraph "Data Sources"
H[ActivityWatch API]
I[Buckets Data]
J[Events Data]
end
subgraph "Consumers"
K[Prometheus]
L[Grafana]
end
A --> B
B --> C
B --> D
B --> E
C --> H
C --> I
D --> H
D --> J
E --> H
F --> B
F --> G
G --> A
K --> A
L --> K
style A fill:#ff6b6b
style B fill:#4ecdc4
style G fill:#ffe66d
```
## Потоки данных
### Metrics Collection Flow
```mermaid
sequenceDiagram
participant Prometheus as Prometheus
participant Server as HTTP Server
participant Collector as Metrics Collector
participant AW as ActivityWatch API
participant Registry as Metrics Registry
Prometheus->>Server: GET /metrics
Server->>Collector: Trigger collection
Collector->>AW: Get buckets list
AW->>Collector: Return buckets
loop For each bucket
Collector->>AW: Get bucket info
AW->>Collector: Return bucket data
Collector->>Collector: Calculate metrics
Collector->>Registry: Update metrics
end
Collector->>Server: Collection complete
Server->>Registry: Format as Prometheus
Registry->>Server: Return formatted metrics
Server->>Prometheus: Return metrics text
```
### Metrics Update Flow
```mermaid
graph LR
A[Scrape Request] --> B[Fetch Buckets]
B --> C[Get Bucket Info]
C --> D[Count Events]
D --> E[Track Active Hosts]
E --> F[Calculate Rates]
F --> G[Update Registry]
G --> H[Format Output]
H --> I[Return to Prometheus]
```
## Ключевые функции
### Инициализация
- `aw_activitywatch_activitywatchexporter_init()` - инициализация exporter
- `aw_activitywatch_activitywatchexporter()` - главный класс exporter
- `aw_activitywatch_main()` - точка входа
### Сбор данных
- `aw_activitywatch_activitywatchexporter_get_buckets()` - получение списка buckets
- `aw_activitywatch_activitywatchexporter_get_bucket_info()` - информация о bucket
- `aw_activitywatch_activitywatchexporter_get_bucket_events()` - события bucket
- `aw_activitywatch_activitywatchexporter_collect_metrics()` - сбор всех метрик
### HTTP Server
- Запуск HTTP сервера на порту 9398
- Endpoint `/metrics` для Prometheus
- Endpoint `/health` для health checks
### Метрики
```python
# Bucket metrics
aw_bucket_events_total{bucket_id, host} - общее количество событий
aw_bucket_events_last_timestamp{bucket_id} - timestamp последнего события
# Host metrics
aw_host_active{host} - хост активен (1/0)
aw_host_last_seen{host} - время последней активности
# Collector metrics
aw_collector_heartbeat{host, collector_type} - heartbeat коллектора
aw_collector_status{host, collector_type, status} - статус коллектора
# Aggregation metrics
aw_aggregation_events_processed_total - обработано событий
aw_aggregation_last_success_timestamp - последний успешный запуск
# Exporter metrics
aw_exporter_scrape_duration_seconds - время обработки scrape
aw_exporter_up - exporter доступен (1/0)
```
## Конфигурация
### Config
```json
{
"aw_base_url": "http://aw-server:5600",
"listen_address": "0.0.0.0",
"listen_port": 9398,
"scrape_interval_seconds": 60,
"bucket_prefixes": [
"aw-watcher-dlp-endpoint",
"aw-watcher-browser-domains",
"aw-watcher-email-outbound",
"aw-watcher-window"
],
"cache_ttl_seconds": 30
}
```
### Environment Variables
```bash
AW_BASE_URL=http://aw-server:5600
EXPORTER_PORT=9398
SCRAPE_INTERVAL=60
LOG_LEVEL=INFO
```
## Пример метрик
### Prometheus Format
```
# HELP aw_bucket_events_total Total number of events in bucket
# TYPE aw_bucket_events_total gauge
aw_bucket_events_total{bucket_id="aw-watcher-dlp-endpoint-WORKSTATION01",host="WORKSTATION01"} 1523.0
aw_bucket_events_total{bucket_id="aw-watcher-browser-domains-WORKSTATION01",host="WORKSTATION01"} 3421.0
# HELP aw_host_active Host is active (1 or 0)
# TYPE aw_host_active gauge
aw_host_active{host="WORKSTATION01"} 1.0
aw_host_active{host="WORKSTATION02"} 0.0
# HELP aw_host_last_seen Unix timestamp of last activity
# TYPE aw_host_last_seen gauge
aw_host_last_seen{host="WORKSTATION01"} 1704110400.0
aw_host_last_seen{host="WORKSTATION02"} 1704100000.0
# HELP aw_exporter_scrape_duration_seconds Duration of scrape
# TYPE aw_exporter_scrape_duration_seconds gauge
aw_exporter_scrape_duration_seconds 0.523
# HELP aw_exporter_up Exporter is up (1 or 0)
# TYPE aw_exporter_up gauge
aw_exporter_up 1.0
```
## Prometheus Configuration
### scrape_config
```yaml
scrape_configs:
- job_name: 'activitywatch'
static_configs:
- targets: ['localhost:9398']
scrape_interval: 60s
scrape_timeout: 30s
metrics_path: /metrics
```
### Alerting Rules
```yaml
groups:
- name: activitywatch_alerts
rules:
- alert: AWCollectorDown
expr: aw_host_active == 0
for: 5m
labels:
severity: warning
annotations:
summary: "ActivityWatch collector down on {{ $labels.host }}"
- alert: AWExporterDown
expr: aw_exporter_up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "ActivityWatch exporter is down"
- alert: AWHighEventRate
expr: rate(aw_bucket_events_total[5m]) > 100
for: 5m
labels:
severity: warning
annotations:
summary: "High event rate on {{ $labels.host }}"
```
## Grafana Dashboard Queries
### Active Hosts
```promql
sum(aw_host_active) by (host)
```
### Events per Bucket
```promql
aw_bucket_events_total
```
### Event Rate
```promql
rate(aw_bucket_events_total[5m])
```
### Host Last Seen
```promql
aw_host_last_seen
```
### Collector Status
```promql
aw_collector_status{status="running"}
```
## Производительность
### Оптимизации
- Кэширование ответов AW API
- Batch запросы к buckets
- Connection pooling
- Асинхронная обработка
### Метрики производительности
```python
performance_metrics = {
"scrape_duration_seconds": 0.5,
"aw_api_latency_seconds": 0.2,
"metrics_count": 50,
"cache_hit_rate": 0.95
}
```
## Docker Deployment
### Dockerfile
```dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY collectors/aw_activitywatch.py .
EXPOSE 9398
CMD ["python", "aw_activitywatch.py"]
```
### Docker Compose
```yaml
services:
aw-exporter:
build: ./sql-exporter
ports:
- "9398:9398"
environment:
- AW_BASE_URL=http://aw-server:5600
- EXPORTER_PORT=9398
depends_on:
- aw-server
restart: unless-stopped
```
## Health Check
### Endpoint: /health
```json
{
"status": "healthy",
"timestamp": "2024-01-01T12:00:00Z",
"aw_server_reachable": true,
"last_scrape_duration_seconds": 0.523,
"metrics_count": 50
}
```
### Health Check Script
```bash
#!/bin/bash
response=$(curl -s http://localhost:9398/health)
status=$(echo $response | jq -r '.status')
if [ "$status" == "healthy" ]; then
echo "Exporter is healthy"
exit 0
else
echo "Exporter is unhealthy"
exit 1
fi
```
## Логирование
### Log Format
```json
{
"timestamp": "2024-01-01T12:00:00Z",
"level": "INFO",
"message": "Metrics collection completed",
"duration_seconds": 0.523,
"buckets_processed": 10,
"metrics_generated": 50
}
```
### Log Levels
- DEBUG - детальная информация о сборе
- INFO - нормальная работа
- WARNING - не критичные проблемы
- ERROR - ошибки при сборе метрик
- CRITICAL - exporter недоступен
## Безопасность
### Рекомендации
- Запускать за reverse proxy (nginx)
- Ограничить доступ по IP
- Использовать HTTPS в production
- Не экспортировать чувствительные данные
### Nginx Config
```nginx
location /metrics {
allow 10.0.0.0/8;
deny all;
proxy_pass http://localhost:9398/metrics;
}
```
+337
View File
@@ -0,0 +1,337 @@
# WebUI Russian Localization Patches - Компонентная диаграмма
## Обзор
Система патчей для русификации и адаптации ActivityWatch WebUI под российские требования.
## Архитектура
```mermaid
graph TB
subgraph "Patch System"
A[Patch Loader]
B[DOM Injection]
C[Style Injection]
D[Navigation Patches]
E[DLP Center Injection]
F[Host Groups Center]
G[Category Builder Patch]
H[Text Translation]
end
subgraph "ActivityWatch WebUI"
I[Original WebUI]
J[DOM Structure]
K[Vue Components]
L[Router]
M[Axios API]
end
subgraph "Patch Targets"
N[Navigation Menu]
O[Activity View]
P[Category Builder]
Q[Buckets View]
R[Settings]
end
A --> B
A --> C
A --> D
A --> E
A --> F
A --> G
A --> H
B --> J
C --> J
D --> L
E --> K
F --> K
G --> K
H --> K
D --> N
E --> K
F --> K
G --> P
H --> O
I --> J
I --> K
I --> L
style B fill:#ff6b6b
style C fill:#ff6b6b
style E fill:#4ecdc4
style F fill:#4ecdc4
style H fill:#ffe66d
```
## Потоки данных
### Patch Application Flow
```mermaid
sequenceDiagram
participant User as Browser
participant WebUI as AW WebUI
participant Loader as Patch Loader
participant DOM as DOM Manipulator
participant API as AW API
User->>WebUI: Load page
WebUI->>Loader: Trigger patch application
Loader->>Loader: Check route
Loader->>DOM: Inject DLP center
DOM->>DOM: Modify navigation
DOM->>DOM: Add Russian styles
Loader->>DOM: Translate text elements
DOM->>DOM: Replace text with Russian
Loader->>API: Fetch Russian data
API->>Loader: Return translated data
Loader->>DOM: Update UI with Russian
DOM->>User: Render patched UI
```
### DLP Center Injection Flow
```mermaid
graph LR
A[Route Check] --> B{Is DLP route?}
B -->|Yes| C[Load DLP Center Component]
B -->|No| D[Skip DLP injection]
C --> E[Inject into DOM]
E --> F[Bind Events]
F --> G[Load DLP Data]
G --> H[Render DLP UI]
```
## Ключевые функции
### Загрузка патчей
- `aw_ru_patch_applypatch()` - применение патча
- `aw_ru_patch_scheduleapplypatch()` - отложенное применение
- `aw_ru_patch_ensurehostgroupsdata()` - обеспечение данных групп хостов
### Инъекция компонентов
- `aw_ru_patch_injectdlpnavigation()` - инъекция DLP навигации
- `aw_ru_patch_injectdlpreviewcenter()` - инъекция центра просмотра DLP
- `aw_ru_patch_injectdlpalertscenter()` - инъекция центра алертов
- `aw_ru_patch_injecthostgroupscenter()` - инъекция центра групп хостов
- `aw_ru_patch_injectpveauditcenter()` - инъекция центра аудита PVE
### Патчи навигации
- `aw_ru_patch_findprimarynavlist()` - поиск главного меню
- `aw_ru_patch_hidenoisenavigation()` - скрытие лишних пунктов
- `aw_ru_patch_removebaddlplinks()` - удаление битых DLP ссылок
- `aw_ru_patch_updatedlplinks()` - обновление DLP ссылок
### Патчи представлений
- `aw_ru_patch_enforcesafeactivityviewforpvehost()` - безопасный вид для PVE
- `aw_ru_patch_collapsereviewevents()` - сворачивание событий ревью
- `aw_ru_patch_collapseruleevents()` - сворачивание событий правил
- `aw_ru_patch_loadbucketevents()` - загрузка событий bucket
### Группы хостов
- `aw_ru_patch_getdefaulthostgroupsconfig()` - конфигурация групп по умолчанию
- `aw_ru_patch_matchhostgroup()` - сопоставление группы хоста
- `aw_ru_patch_renderhostgroupcards()` - рендер карточек групп
- `aw_ru_patch_hosthasbucketprefix()` - проверка префикса bucket
### Перевод
- `aw_ru_patch_translateattributes()` - перевод атрибутов
- `aw_ru_patch_normalizetext()` - нормализация текста
- `aw_ru_patch_escapehtml()` - экранирование HTML
### Утилиты
- `aw_ru_patch_replacetext()` - замена текста
- `aw_ru_patch_walk()` - обход DOM
- `aw_ru_patch_ishomeroute()` - проверка домашнего маршрута
- `aw_ru_patch_ispvelikehost()` - проверка PVE хоста
## Структура патчей
### Патчи по маршрутам
```javascript
const routePatches = {
'/': 'home-patch',
'/activity': 'activity-patch',
'/buckets': 'buckets-patch',
'/category-builder': 'category-builder-patch',
'/dlp/review': 'dlp-review-patch',
'/dlp/rules': 'dlp-rules-patch',
'/dlp/alerts': 'dlp-alerts-patch'
};
```
### Инъекции DLP компонентов
```javascript
const dlpInjections = {
navigation: 'inject-dlp-nav',
reviewCenter: 'inject-dlp-review',
rulesManager: 'inject-dlp-rules',
alertsCenter: 'inject-dlp-alerts'
};
```
### Русификация
```javascript
const translations = {
'Activity': 'Активность',
'Buckets': 'Бакеты',
'Duration': 'Длительность',
'Events': 'События',
'Settings': 'Настройки'
};
```
## Конфигурация
### Host Groups Config
```json
{
"host_groups": [
{
"id": "workstations",
"name": "Рабочие станции",
"hosts": ["WORKSTATION01", "WORKSTATION02"],
"color": "#4ecdc4"
},
{
"id": "servers",
"name": "Серверы",
"hosts": ["SERVER01", "SERVER02"],
"color": "#ff6b6b"
}
]
}
```
### DLP Settings
```json
{
"dlp_enabled": true,
"review_center_enabled": true,
"alerts_center_enabled": true,
"auto_refresh_interval": 30,
"default_severity_filter": "all"
}
```
## Компоненты UI
### DLP Review Center
- Список инцидентов
- Фильтрация по типам
- Детальный просмотр
- Архивирование
- Экспорт
### DLP Rules Manager
- Список правил
- Создание/редактирование
- Включение/выключение
- Тестирование правил
- Импорт/экспорт
### DLP Alerts Center
- Алерты в реальном времени
- Группировка по серьезности
- История алертов
- Подписки на алерты
### Host Groups Center
- Управление группами хостов
- Визуализация по группам
- Агрегированная статистика
- Сравнение групп
## Интеграция с ActivityWatch
### API Endpoints
```javascript
// Получение DLP инцидентов
GET /api/0/buckets/{bucket_id}/events?filters=dlp_incident
// Получение правил DLP
GET /api/0/dlp/rules
// Сохранение инцидента
POST /api/0/dlp/incident
// Получение групп хостов
GET /api/0/host_groups
```
### Bucket Prefixes
```
aw-watcher-dlp-endpoint-*
aw-watcher-browser-domains-*
aw-watcher-email-outbound-*
```
## Стили
### Russian UI Styles
```css
.ru-font {
font-family: 'Segoe UI', 'Roboto', sans-serif;
}
.ru-nav-item {
padding: 8px 16px;
border-radius: 4px;
}
.ru-dlp-card {
border-left: 4px solid #ff6b6b;
background: #fff5f5;
}
```
## Производительность
### Оптимизации
- Lazy loading патчей
- Кэширование переводов
- Debouncing обновлений DOM
- Virtual scrolling для больших списков
### Метрики
- Время применения патча
- Количество модификаций DOM
- Частота перерисовки
- Размер загружаемых переводов
## Отладка
### Логирование патчей
```javascript
console.log('[AW-RU-Patch] Applying patch:', patchName);
console.log('[AW-RU-Patch] Route:', currentRoute);
console.log('[AW-RU-Patch] Elements modified:', count);
```
### Режим разработки
```javascript
const DEBUG_MODE = true;
if (DEBUG_MODE) {
window.AW_RU_PATCHES = {
applied: [],
skipped: [],
errors: []
};
}
```
## Совместимость
### Поддерживаемые версии ActivityWatch
- v0.12.x
- v0.13.x
- v0.14.x
### Поддерживаемые браузеры
- Chrome 90+
- Firefox 88+
- Edge 90+
- Safari 14+