Skip to content

Text Output Mode

Relevant source files

The following files were used as context for generating this wiki page:

Text output mode is the default capture mode for eCapture, which displays captured plaintext data directly to the console or log files in human-readable format. Unlike pcap mode (4.2) which saves packets for Wireshark, or keylog mode (4.3) which only captures TLS keys, text mode provides real-time visibility into decrypted communication content with minimal configuration.

For remote/GUI integration using protobuf format, see Protobuf and External Integration. For general event processing architecture, see Event Processing Pipeline.


Overview

Text mode operates as a streaming output mechanism that:

  • Default behavior: Activates when no -m flag is specified or explicitly set with -m text
  • Real-time display: Events are processed and displayed as they occur
  • Protocol-aware formatting: Automatically detects and formats HTTP/1.x, HTTP/2, and other protocols
  • Flexible output: Supports both console output and file logging
  • Metadata enrichment: Includes process context (PID, command name, network tuple) with each event

Starting from version v0.7.0, text mode no longer captures TLS master keys; use keylog mode (4.3) for key extraction.

Sources: README.md:249-253, CHANGELOG.md:697-723


Configuration

Command Line Flags

Text mode is controlled through several flags passed to capture modules (tls, gotls, gnutls, etc.):

FlagTypeDefaultDescription
-m textstring(default)Explicitly set text output mode
--hexbooleanfalseOutput payload in hexadecimal dump format
--logaddrstring""Network address for log forwarding
-w / --outputstring""Write output to specified file instead of stdout
--truncateuint640Truncate event payloads to specified size (bytes)

Logger Configuration

The text output system uses two writer implementations:

  1. CollectorWriter: Uses zerolog for structured console/file logging (default for text mode)
  2. ProtobufWriter: Marshals events to protobuf format for WebSocket transmission

Sources: pkg/event_processor/processor.go:42-49, user/event/ievent.go:54-70


Output Format

Standard Text Format

Each captured event is formatted with metadata and payload:

UUID:<PID>_<TID>_<Comm>_<FD>_<DataType>_<Tuple>, Name:<ParserType>, Type:<TypeID>, Length:<Bytes>
PID:<PID>, Comm:<CommandName>, Src:<SrcIP>:<SrcPort>, Dest:<DstIP>:<DstPort>,
<Formatted Payload>

Example output from OpenSSL capture:

2024-09-15T11:50:31Z ??? UUID:233479_233479_curl_5_1_39.156.66.10:443, Name:HTTPRequest, Type:1, Length:73
GET / HTTP/1.1
Host: baidu.com
Accept: */*
User-Agent: curl/7.81.0

Hexadecimal Mode

When --hex flag is enabled, payloads are displayed as hexadecimal dump instead of formatted text:

go
// Hexadecimal dump format (example)
00000000  47 45 54 20 2f 20 48 54  54 50 2f 31 2e 31 0d 0a  |GET / HTTP/1.1..|
00000010  48 6f 73 74 3a 20 62 61  69 64 75 2e 63 6f 6d 0d  |Host: baidu.com.|

Sources: pkg/event_processor/iworker.go:192-194, README_CN.md:103-126


Event Flow Architecture

Data Pipeline

Flow description:

  1. eBPF Events: Captured by uprobes/kprobes and sent through PERF_EVENT_ARRAY maps
  2. Module Decode: Module-specific decoder (e.g., OpenSSL, GoTLS) parses raw eBPF event into IEventStruct
  3. Event Dispatch: EventProcessor receives events and routes them to UUID-specific workers
  4. Worker Accumulation: Each eventWorker buffers events in payload until a display trigger occurs
  5. Display Trigger: 100ms ticker fires when no new data arrives
  6. Parser Selection: System detects protocol (HTTP/HTTP2/Default) and applies appropriate formatter
  7. Output: Formatted data written to console or file via CollectorWriter

Sources: pkg/event_processor/processor.go:65-89, pkg/event_processor/iworker.go:262-306


Parser Selection and Formatting

Parser Detection Flow

Parser Types

ParserDetection MethodOutput FormatParserType ID
HTTPRequesthttp.ReadRequest() successHTTP request headers + body1
HTTPResponsehttp.ReadResponse() successHTTP response headers + body3
HTTP2RequestHTTP/2 frame preface detectionHTTP/2 frame-by-frame display2
HTTP2ResponseHTTP/2 frame detectionHTTP/2 frame-by-frame display4
DefaultParserFallback if all failRaw text or hex dump0

Sources: pkg/event_processor/iparser.go:85-115, pkg/event_processor/http_request.go:83-92, pkg/event_processor/http_response.go:94-102


CollectorWriter Implementation

Text Output Path

The CollectorWriter wraps a zerolog.Logger instance and implements the standard io.Writer interface, enabling seamless integration with the event processing pipeline:

go
// CollectorWriter struct (conceptual)
type CollectorWriter struct {
    logger *zerolog.Logger
}

func (e CollectorWriter) Write(p []byte) (n int, err error) {
    return e.logger.Write(p)
}

Output format includes:

  • Timestamp (RFC3339 format)
  • Log level (INFO/WARN/ERROR)
  • Event UUID
  • Parser name
  • Formatted payload

Sources: user/event/ievent.go:54-70, pkg/event_processor/iworker.go:198-212


Worker Lifecycle and Display Triggers

Event Worker State Machine

Display Trigger Logic

The eventWorker uses a 100ms ticker to detect idle periods:

ConditionAction
tickerCount > 10 (1 second)Trigger Display()
After Display()Reset payload buffer and parser
LifeCycleStateDefault modeDelete worker and exit
LifeCycleStateSock modeContinue running, start new ticker

Truncation behavior:

If truncateSize is configured and payload.Len() >= truncateSize, the worker:

  1. Truncates payload to specified size: payload.Truncate(tsize)
  2. Logs truncation message
  3. Stops accepting new events for that UUID

Sources: pkg/event_processor/iworker.go:262-306, pkg/event_processor/iworker.go:236-245


Configuration Examples

Basic Text Mode (Console Output)

bash
# OpenSSL module, text mode, console output
sudo ecapture tls

# GoTLS module, text mode with hex dump
sudo ecapture gotls --elfpath=/path/to/go_binary --hex

# Target specific PID
sudo ecapture tls --pid=1234

File Output

bash
# Write to file instead of console
sudo ecapture tls -w output.log

# With truncation to limit memory usage
sudo ecapture tls -w output.log --truncate=4096

Filtered Output

bash
# Capture only specific process
sudo ecapture tls --pid=5678 -w tls_capture.log

# Capture specific user's traffic
sudo ecapture tls --uid=1000

Sources: README.md:72-149, README_CN.md:74-126


HTTP/HTTP2 Formatting Examples

HTTP/1.x Request Display

2024-09-15T11:50:31Z ??? UUID:233479_233479_curl_5_1_39.156.66.10:443, Name:HTTPRequest, Type:1, Length:73
GET / HTTP/1.1
Host: baidu.com
Accept: */*
User-Agent: curl/7.81.0

HTTP/1.x Response Display

2024-09-15T11:50:32Z ??? UUID:233479_233479_curl_5_0_39.156.66.10:443, Name:HTTPResponse, Type:3, Length:357
HTTP/1.1 302 Moved Temporarily
Content-Length: 161
Connection: keep-alive
Content-Type: text/html
Date: Sun, 15 Sep 2024 11:50:30 GMT
Location: http://www.baidu.com/
Server: bfe/1.0.8.18

<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
</body></html>

HTTP/2 Request Display

2024-09-15T11:51:53Z ??? UUID:233851_233851_curl_5_1_172.16.71.1:51837, Name:HTTP2Request, Type:2, Length:304

Frame Type	=>	SETTINGS

Frame Type	=>	WINDOW_UPDATE

Frame Type	=>	HEADERS
header field ":method" = "GET"
header field ":path" = "/"
header field ":scheme" = "https"
header field ":authority" = "google.com"
header field "user-agent" = "curl/7.81.0"
header field "accept" = "*/*"

Sources: README.md:102-148, README_CN.md:103-126


Protocol-Specific Formatting

HTTP Request Formatter

The HTTPRequest parser processes HTTP/1.x requests:

  1. Detection: Calls http.ReadRequest() on first chunk
  2. Accumulation: Buffers subsequent chunks until complete
  3. Decompression: Handles Content-Encoding: gzip automatically
  4. Output: Uses httputil.DumpRequest() for formatted display

Key functions:

HTTP Response Formatter

The HTTPResponse parser handles server responses:

  1. Detection: Calls http.ReadResponse() on payload
  2. Body handling: Reads full response body with io.ReadAll()
  3. Compression: Detects and decompresses gzip-encoded bodies
  4. Special cases: Handles chunked transfer encoding and truncated bodies

Key functions:

Default Parser

When no specialized parser matches, DefaultParser provides:

  • Raw byte output for binary data
  • C-string to Go string conversion for text
  • Hexadecimal dump for non-printable characters

Detection logic pkg/event_processor/iparser.go:157-160:

go
// Display decision based on first byte
if b[0] < 32 || b[0] > 126 {
    return []byte(hex.Dump(b))  // Non-printable: hex dump
}
return []byte(CToGoString(b))  // Printable: text

Sources: pkg/event_processor/http_request.go:105-157, pkg/event_processor/http_response.go:115-175, pkg/event_processor/iparser.go:117-166


Memory Management and Truncation

Truncation Mechanism

To prevent memory exhaustion from large payloads, text mode supports truncation:

go
// Truncation check before writing events
tsize := int(processor.truncateSize)
if tsize > 0 && payload.Len() >= tsize {
    payload.Truncate(tsize)
    Log(fmt.Sprintf("Events truncated, size: %d bytes\n", tsize))
    return  // Stop accepting more events
}

Configuration:

  • Set via --truncate=<bytes> flag
  • Default: 0 (no truncation)
  • When triggered: Worker stops accumulating and displays truncated content

Memory Efficiency Improvements

Version 1.1.0 introduced memory optimizations:

  • Redesigned truncation logic to reduce memory cost in text mode
  • Per-worker buffering instead of global accumulation
  • Early truncation prevents oversized payloads from being allocated

Sources: pkg/event_processor/iworker.go:236-245, CHANGELOG.md:163-164


Metadata and Context Enrichment

UUID Format

Each event includes a UUID that encodes connection context:

Standard format:

<PID>_<TID>_<Comm>_<FD>_<DataType>_<SrcIP:SrcPort-DstIP:DstPort>

Socket lifecycle format (for connection-bound workers):

sock:<PID>_<TID>_<Comm>_<FD>_<DataType>_<SrcIP:SrcPort-DstIP:DstPort>_<SocketPtr>

The UUID parser extracts:

  • uuidOutput: Display format (without socket pointer)
  • DestroyUUID: Socket pointer for lifecycle management
  • ewLifeCycleState: Worker lifecycle mode

Sources: pkg/event_processor/iworker.go:100-123, user/event/ievent.go:39

Event Base Structure

Every event includes common metadata fields:

FieldTypeDescription
PIDuint32Process ID
PNamestringCommand name
SrcIPstringSource IP address
SrcPortuint16Source port
DstIPstringDestination IP address
DstPortuint16Destination port
Timestampuint64Kernel timestamp (nanoseconds)

This metadata is displayed in the formatted output header.

Sources: pkg/event_processor/iworker.go:200-212


Integration with Other Modules

Module-Specific Text Output

Each capture module (OpenSSL, GoTLS, GnuTLS, etc.) generates events that flow through the text output pipeline:

ModuleEvent TypesText Mode Support
OpenSSL (3.1.1)SSLDataEventFull HTTP/HTTP2 parsing
GoTLS (3.1.3)SSLDataEventFull HTTP/HTTP2 parsing
GnuTLS (3.1.4)SSLDataEventFull HTTP/HTTP2 parsing
Bash (3.2.1)BashEventCommand-line text display
MySQL (3.2.2)MySQLEventSQL query text display
Postgres (3.2.2)PostgresEventSQL query text display

All modules share the same EventProcessor and output formatting pipeline.

Sources: README.md:152-161


Comparison with Other Output Modes

FeatureText ModePcap Mode (4.2)Keylog Mode (4.3)
Real-time display✓ Console/log output× Buffered to file× File only
Protocol parsing✓ HTTP/HTTP2 formatted× Raw packets× Keys only
Master key capture× (since v0.7.0)✓ DSB block in pcapng✓ SSLKEYLOGFILE format
Wireshark compatible×✓ Native support✓ Via keylog file
Memory usageLow (streaming)Higher (packet buffering)Minimal (keys only)
Use caseLive monitoringForensic analysisOffline decryption

Sources: CHANGELOG.md:697-723


Error Handling and Logging

Event Processing Errors

When parsers encounter errors during formatting:

  1. HTTP/HTTP2 parse errors: Logged but do not stop processing
  2. Truncation errors: Logged with truncation size
  3. Write errors: Logged but events continue to flow
  4. EOF errors: Ignored (normal for incomplete streams)

Example error messages:

eventWorker: write events failed, unknow eventWorker status: 2
ew.parser uuid: sock:1234_1234_curl_5_1... type 1 write payload 2048 bytes, error:unexpected EOF

Worker Error Handling

The eventWorker.Run() loop handles errors gracefully:

  • Incoming channel full: Drops event, logs error
  • Outgoing channel full: Logs error, continues processing
  • Parser errors: Logged but not fatal, falls back to hex dump

Sources: pkg/event_processor/iworker.go:154-172, pkg/event_processor/iworker.go:254-257


Performance Considerations

Throughput and Latency

Text mode characteristics:

  • Latency: 100ms baseline (ticker interval) + parsing time
  • Throughput: Limited by console/file I/O, not CPU-bound
  • CPU usage: Parser overhead for HTTP/HTTP2 detection and formatting
  • Memory: Configurable via --truncate flag

Optimization Strategies

  1. Use truncation for high-volume captures to prevent memory growth
  2. Write to file instead of console for better throughput
  3. Filter by PID/UID to reduce event volume
  4. Use hex mode to skip protocol parsing overhead

Sources: CHANGELOG.md:163-164, pkg/event_processor/iworker.go:236-245

Text Output Mode has loaded