Logging & Monitoring
This section covers TrigDroid’s comprehensive logging capabilities and monitoring features for security testing and analysis.
Important
Proper logging is crucial for security research. TrigDroid provides detailed logging to help you understand application behavior changes and detect potential threats.
Logging Architecture
TrigDroid implements a layered logging architecture that captures different aspects of the testing process:
Logging Levels
TrigDroid uses standard Python logging levels with security-focused categorization:
DEBUG: Detailed execution information, API call traces, internal state changes
INFO: General test execution flow, configuration details, phase transitions
WARNING: Unexpected behaviors, potential issues, configuration warnings
ERROR: Test failures, device connection issues, critical errors
CRITICAL: Security-relevant events, malicious behavior detection
Logging Categories
System Logging
Core system operations and infrastructure events:
import logging
from trigdroid import TrigDroidAPI, TestConfiguration
# Configure logging level
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('trigdroid')
config = TestConfiguration(
package="com.example.app",
log_level="DEBUG" # Detailed logging
)
with TrigDroidAPI(config) as api:
# System logs automatically captured
result = api.run_tests()
Device Interaction Logging
ADB commands, device state changes, and hardware interactions:
config = TestConfiguration(
package="com.test.app",
log_device_interactions=True, # Enable device logging
log_adb_commands=True # Log ADB command execution
)
Application Behavior Logging
Application-specific events and behavioral changes:
config = TestConfiguration(
package="com.suspicious.app",
log_app_lifecycle=True, # Activity lifecycle events
log_permission_changes=True, # Permission grant/revoke events
log_network_activity=True # Network connections and data transfer
)
Frida Instrumentation Logging
Runtime hooking and dynamic analysis events:
config = TestConfiguration(
package="com.analysis.target",
frida_hooks=True,
log_frida_hooks=True, # Hook invocation logging
log_api_calls=True, # Android API call logging
log_method_arguments=True # Method argument capture
)
Security Event Logging
High-priority security-relevant events:
config = TestConfiguration(
package="com.malware.sample",
log_security_events=True, # Malicious behavior indicators
log_anti_analysis=True, # Anti-analysis technique detection
log_evasion_attempts=True # Evasion behavior logging
)
Log Configuration
Configuration File
Create a logging configuration file for detailed control:
# logging_config.yaml
version: 1
formatters:
detailed:
format: '[{asctime}] {levelname:8} {name}: {message}'
style: '{'
security:
format: '[{asctime}] SECURITY-{levelname}: {name}: {message}'
style: '{'
handlers:
console:
class: logging.StreamHandler
level: INFO
formatter: detailed
stream: ext://sys.stdout
file:
class: logging.handlers.RotatingFileHandler
level: DEBUG
formatter: detailed
filename: trigdroid.log
maxBytes: 10485760 # 10MB
backupCount: 5
security_file:
class: logging.FileHandler
level: WARNING
formatter: security
filename: security_events.log
loggers:
trigdroid:
level: DEBUG
handlers: [console, file]
propagate: false
trigdroid.security:
level: WARNING
handlers: [security_file]
propagate: false
root:
level: WARNING
handlers: [console]
Programmatic Configuration
Configure logging programmatically:
import logging
import logging.config
from trigdroid import TrigDroidAPI, TestConfiguration
# Load logging configuration
with open('logging_config.yaml', 'r') as f:
logging.config.dictConfig(yaml.safe_load(f))
# Create logger
logger = logging.getLogger('trigdroid')
# Configure TrigDroid with custom logging
config = TestConfiguration(
package="com.example.app",
logger=logger,
log_level="DEBUG",
log_format="[{timestamp}] {level}: {module}: {message}"
)
Log Output Examples
System Execution Logs
[2024-01-15 10:30:15] INFO trigdroid.api: Starting TrigDroid test session
[2024-01-15 10:30:15] INFO trigdroid.device: Connected to device emulator-5554
[2024-01-15 10:30:16] INFO trigdroid.config: Loaded configuration for com.example.app
[2024-01-15 10:30:16] DEBUG trigdroid.setup: Installing application package
[2024-01-15 10:30:18] INFO trigdroid.runner: Starting sensor test runner
[2024-01-15 10:30:18] DEBUG trigdroid.sensors: Setting accelerometer to high activity
[2024-01-15 10:30:19] INFO trigdroid.app: Application launched successfully
Device Interaction Logs
[2024-01-15 10:30:20] DEBUG trigdroid.adb: adb shell am start -n com.example.app/.MainActivity
[2024-01-15 10:30:21] DEBUG trigdroid.device: Battery level changed: 100% -> 15%
[2024-01-15 10:30:22] DEBUG trigdroid.network: WiFi state changed: connected -> disconnected
[2024-01-15 10:30:23] DEBUG trigdroid.sensors: Gyroscope data injected: x=1.2, y=2.1, z=0.8
Frida Hook Logs
[2024-01-15 10:30:25] DEBUG trigdroid.frida: Hook attached to android.telephony.TelephonyManager.getDeviceId
[2024-01-15 10:30:26] INFO trigdroid.hooks: API call intercepted: TelephonyManager.getDeviceId()
[2024-01-15 10:30:26] DEBUG trigdroid.hooks: Return value modified: 'real_imei' -> 'fake_imei_123'
[2024-01-15 10:30:27] WARNING trigdroid.hooks: Suspicious call detected: Runtime.exec("su")
Security Event Logs
[2024-01-15 10:30:30] WARNING trigdroid.security: Anti-emulator check detected in com.example.app
[2024-01-15 10:30:31] ERROR trigdroid.security: Potential malicious behavior: Attempting to access /system/bin/su
[2024-01-15 10:30:32] CRITICAL trigdroid.security: Data exfiltration detected: Unauthorized network connection to 192.168.1.100:8080
[2024-01-15 10:30:33] ERROR trigdroid.security: Root detection bypass attempted
Log Analysis and Monitoring
Real-time Monitoring
Monitor logs in real-time during test execution:
import logging
from trigdroid import TrigDroidAPI, TestConfiguration
class SecurityEventHandler(logging.Handler):
def emit(self, record):
if record.levelno >= logging.WARNING:
if 'malicious' in record.getMessage().lower():
# Alert on potential malicious behavior
self.send_security_alert(record.getMessage())
# Add custom handler
security_handler = SecurityEventHandler()
security_logger = logging.getLogger('trigdroid.security')
security_logger.addHandler(security_handler)
Log Aggregation
Collect and aggregate logs from multiple test sessions:
import json
import logging.handlers
from trigdroid import TrigDroidAPI, TestConfiguration
# JSON formatter for structured logs
class JSONFormatter(logging.Formatter):
def format(self, record):
log_data = {
'timestamp': self.formatTime(record),
'level': record.levelname,
'logger': record.name,
'message': record.getMessage(),
'module': record.module,
'function': record.funcName,
'line': record.lineno
}
return json.dumps(log_data)
# Configure JSON logging
json_handler = logging.handlers.RotatingFileHandler(
'trigdroid_structured.log', maxBytes=50*1024*1024, backupCount=10
)
json_handler.setFormatter(JSONFormatter())
logger = logging.getLogger('trigdroid')
logger.addHandler(json_handler)
Log Analysis Tools
Built-in Analysis
TrigDroid provides built-in log analysis capabilities:
from trigdroid.analysis import LogAnalyzer
# Analyze test logs
analyzer = LogAnalyzer('trigdroid.log')
# Extract security events
security_events = analyzer.extract_security_events()
# Identify behavioral patterns
patterns = analyzer.identify_patterns()
# Generate summary report
report = analyzer.generate_report()
print(report)
Custom Analysis Scripts
Create custom analysis scripts for specific use cases:
import re
import json
from collections import defaultdict
def analyze_api_calls(log_file):
"""Analyze API call patterns from Frida hook logs."""
api_calls = defaultdict(int)
suspicious_calls = []
with open(log_file, 'r') as f:
for line in f:
if 'API call intercepted' in line:
# Extract API call name
match = re.search(r'API call intercepted: (.+)\(', line)
if match:
api_name = match.group(1)
api_calls[api_name] += 1
# Flag suspicious APIs
if any(sus in api_name.lower() for sus in ['exec', 'root', 'su', 'system']):
suspicious_calls.append((line.strip(), api_name))
return api_calls, suspicious_calls
# Usage
calls, suspicious = analyze_api_calls('trigdroid.log')
print(f"Total API calls: {len(calls)}")
print(f"Suspicious calls: {len(suspicious)}")
Performance Monitoring
Execution Time Tracking
Monitor test execution performance:
import time
import logging
from functools import wraps
def timed_operation(operation_name):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
logger = logging.getLogger('trigdroid.performance')
start_time = time.time()
logger.info(f"Starting {operation_name}")
try:
result = func(*args, **kwargs)
duration = time.time() - start_time
logger.info(f"{operation_name} completed in {duration:.2f}s")
return result
except Exception as e:
duration = time.time() - start_time
logger.error(f"{operation_name} failed after {duration:.2f}s: {e}")
raise
return wrapper
return decorator
Resource Usage Monitoring
Track system resource usage during testing:
import psutil
import logging
import threading
import time
class ResourceMonitor:
def __init__(self, interval=5):
self.interval = interval
self.monitoring = False
self.logger = logging.getLogger('trigdroid.resources')
def start_monitoring(self):
self.monitoring = True
threading.Thread(target=self._monitor, daemon=True).start()
def stop_monitoring(self):
self.monitoring = False
def _monitor(self):
while self.monitoring:
cpu_percent = psutil.cpu_percent()
memory = psutil.virtual_memory()
self.logger.info(
f"Resource usage - CPU: {cpu_percent}%, "
f"Memory: {memory.percent}% ({memory.used/1024/1024:.1f}MB)"
)
time.sleep(self.interval)
Best Practices
Logging Security Guidelines
Sensitive Data: Never log passwords, tokens, or personally identifiable information
Data Classification: Classify logs based on sensitivity (public, internal, confidential)
Retention Policy: Implement appropriate log retention policies
Access Control: Restrict access to security-relevant logs
Log Management
Rotation: Use log rotation to prevent disk space issues
Compression: Compress old log files to save space
Centralization: Consider centralized logging for multiple test environments
Backup: Regularly backup important log files
Analysis Efficiency
Structured Logging: Use structured formats (JSON) for easier parsing
Indexing: Index logs for faster searching and analysis
Filtering: Implement log filtering to reduce noise
Alerting: Set up automated alerting for critical security events
Integration Examples
ELK Stack Integration
Integrate with Elasticsearch, Logstash, and Kibana:
import logging
from pythonjsonlogger import jsonlogger
# Configure JSON logging for ELK
logHandler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter()
logHandler.setFormatter(formatter)
logger = logging.getLogger('trigdroid')
logger.addHandler(logHandler)
logger.setLevel(logging.INFO)
SIEM Integration
Send security events to Security Information and Event Management systems:
import logging
import requests
class SIEMHandler(logging.Handler):
def __init__(self, siem_url, api_key):
super().__init__()
self.siem_url = siem_url
self.api_key = api_key
def emit(self, record):
if record.levelno >= logging.WARNING:
event_data = {
'timestamp': self.formatTime(record),
'severity': record.levelname,
'source': 'TrigDroid',
'message': record.getMessage(),
'category': 'mobile_security_testing'
}
try:
requests.post(
self.siem_url,
json=event_data,
headers={'Authorization': f'Bearer {self.api_key}'},
timeout=5
)
except Exception:
# Don't fail the main operation if SIEM is unavailable
pass
For more advanced logging configurations and analysis techniques, see the Development guide.