Trojan Rust

Analytics

Connection event tracking with ClickHouse

trojan-rs includes an optional analytics module for tracking connection events. Events are buffered and written to ClickHouse for analysis.

Overview

Connection → Event Collector → Buffer → ClickHouse Writer → ClickHouse DB

The analytics system is double-gated:

  1. Compile-time: The analytics feature flag must be enabled
  2. Runtime: The [analytics] config section must be present with enabled = true

Configuration

[analytics]
enabled = true

[analytics.clickhouse]
url = "http://localhost:8123"        # ClickHouse HTTP endpoint
database = "trojan"                  # Database name
table = "connection_events"          # Table name
username = "default"                 # ClickHouse username
password = ""                        # ClickHouse password
connect_timeout_secs = 5
request_timeout_secs = 10

[analytics.buffer]
max_events = 1000                    # Max buffered events before flush
flush_interval_secs = 10             # Flush interval

[analytics.sampling]
rate = 1.0                           # Sampling rate (0.0 to 1.0)
allowed_users = []                   # Always sample these user hashes

[analytics.privacy]
record_ip = true                     # Record client IP addresses
mask_user_id = false                 # Mask user identifiers
record_sni = true                    # Record SNI values

Event Fields

Each connection event captures:

FieldTypeDescription
timestampDateTimeEvent timestamp
connection_idStringUnique connection identifier
client_ipStringClient IP address
client_portUInt16Client port
user_hashStringSHA-224 password hash
commandStringTrojan command (connect/udp)
target_hostStringDestination hostname
target_portUInt16Destination port
bytes_upUInt64Bytes uploaded
bytes_downUInt64Bytes downloaded
duration_msUInt64Connection duration
close_reasonStringWhy the connection closed
tls_versionStringTLS version used
tls_cipherStringTLS cipher suite
sniStringServer Name Indication
alpnStringNegotiated ALPN protocol
auth_resultStringAuthentication result
transportStringTransport type (tcp/websocket)

Buffering

Events are collected in memory and flushed to ClickHouse when either:

  • The buffer reaches max_events events
  • The flush_interval_secs timer fires

This batches writes for efficiency. If ClickHouse is unreachable, events are dropped after the buffer fills.

Sampling

Control the volume of recorded events:

[analytics.sampling]
rate = 0.1                           # Sample 10% of connections
allowed_users = ["abc123..."]        # Always sample these users
  • rate = 1.0 records all connections
  • rate = 0.0 disables recording (except allowed users)
  • Users in allowed_users are always sampled regardless of rate

Privacy Controls

[analytics.privacy]
record_ip = false                    # Omit client IP addresses
mask_user_id = true                  # Hash user identifiers
record_sni = false                   # Omit SNI values

Use these settings to comply with privacy requirements.

ClickHouse Schema

The analytics module creates a table with the fields listed above. It also supports materialized views for common queries:

  • Hourly traffic summary — Aggregated bytes by user per hour
  • Connection count by target — Top destinations
  • Error rate tracking — Authentication failures and connection errors

Example Queries

Traffic by user (last 24 hours)

SELECT
    user_hash,
    sum(bytes_up) AS total_up,
    sum(bytes_down) AS total_down,
    count() AS connections
FROM connection_events
WHERE timestamp > now() - INTERVAL 1 DAY
GROUP BY user_hash
ORDER BY total_down DESC

Top destinations

SELECT
    target_host,
    count() AS connections,
    sum(bytes_down) AS total_bytes
FROM connection_events
WHERE timestamp > now() - INTERVAL 1 DAY
GROUP BY target_host
ORDER BY connections DESC
LIMIT 20

Authentication failures

SELECT
    client_ip,
    count() AS failures
FROM connection_events
WHERE auth_result != 'success'
    AND timestamp > now() - INTERVAL 1 HOUR
GROUP BY client_ip
ORDER BY failures DESC

On this page