Skip to content

Commit 1b30ff2

Browse files
jbachorikclaude
andcommitted
feat(profiling): Add diagnostics mode to convert-jfr.sh script
Enhanced the conversion script with detailed diagnostic output showing: - Input file sizes (individual and total) - Output file size - Wall-clock conversion time - Compression ratio (output vs input size) - Space savings (bytes and percentage) Usage: ./convert-jfr.sh --diagnostics recording.jfr output.pb Example output: [DIAG] Input: recording.jfr (89.3KB) [DIAG] Total input size: 89.3KB [DIAG] === Conversion Diagnostics === [DIAG] Wall time: 127.3ms [DIAG] Output size: 45.2KB [DIAG] Size ratio: 50.6% of input [DIAG] Savings: 44.1KB (49.4% reduction) Features: - Cross-platform file size detection (macOS and Linux) - Nanosecond-precision timing - Human-readable size formatting (B, KB, MB, GB) - Automatic compression ratio calculation - Color-coded diagnostic output (cyan) Updated CLI.md with: - --diagnostics option documentation - Example output showing diagnostic information - Updated feature list 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 7b9529a commit 1b30ff2

File tree

2 files changed

+162
-5
lines changed

2 files changed

+162
-5
lines changed

dd-java-agent/agent-profiling/profiling-otel/convert-jfr.sh

Lines changed: 140 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@
1212
# --json Output in JSON format instead of protobuf
1313
# --pretty Pretty-print JSON output (implies --json)
1414
# --include-payload Include original JFR payload in OTLP output
15+
# --diagnostics Show detailed diagnostics (file sizes, conversion time)
1516
# --help Show this help message
1617
#
1718
# Examples:
1819
# ./convert-jfr.sh recording.jfr output.pb
1920
# ./convert-jfr.sh --json recording.jfr output.json
2021
# ./convert-jfr.sh --pretty recording.jfr output.json
21-
# ./convert-jfr.sh file1.jfr file2.jfr combined.pb
22+
# ./convert-jfr.sh --diagnostics file1.jfr file2.jfr combined.pb
2223

2324
set -e
2425

@@ -30,11 +31,65 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
3031
RED='\033[0;31m'
3132
GREEN='\033[0;32m'
3233
BLUE='\033[0;34m'
34+
YELLOW='\033[1;33m'
35+
CYAN='\033[0;36m'
3336
NC='\033[0m'
3437

3538
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
3639
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
3740
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
41+
log_diagnostic() { echo -e "${CYAN}[DIAG]${NC} $1"; }
42+
43+
# Get file size in human-readable format
44+
get_file_size() {
45+
local file="$1"
46+
if [ -f "$file" ]; then
47+
# Use du for cross-platform compatibility
48+
du -h "$file" | cut -f1
49+
else
50+
echo "N/A"
51+
fi
52+
}
53+
54+
# Get file size in bytes
55+
get_file_size_bytes() {
56+
local file="$1"
57+
if [ -f "$file" ]; then
58+
# Cross-platform file size in bytes
59+
if [[ "$OSTYPE" == "darwin"* ]]; then
60+
stat -f%z "$file"
61+
else
62+
stat -c%s "$file"
63+
fi
64+
else
65+
echo "0"
66+
fi
67+
}
68+
69+
# Format bytes to human-readable
70+
format_bytes() {
71+
local bytes=$1
72+
if [ "$bytes" -lt 1024 ]; then
73+
echo "${bytes}B"
74+
elif [ "$bytes" -lt 1048576 ]; then
75+
echo "$(awk "BEGIN {printf \"%.1f\", $bytes/1024}")KB"
76+
elif [ "$bytes" -lt 1073741824 ]; then
77+
echo "$(awk "BEGIN {printf \"%.1f\", $bytes/1048576}")MB"
78+
else
79+
echo "$(awk "BEGIN {printf \"%.1f\", $bytes/1073741824}")GB"
80+
fi
81+
}
82+
83+
# Calculate compression ratio
84+
calc_compression_ratio() {
85+
local input_size=$1
86+
local output_size=$2
87+
if [ "$input_size" -eq 0 ]; then
88+
echo "N/A"
89+
else
90+
awk "BEGIN {printf \"%.1f%%\", ($output_size / $input_size) * 100}"
91+
fi
92+
}
3893

3994
show_help() {
4095
cat << EOF
@@ -47,6 +102,7 @@ Options:
47102
--json Output in JSON format instead of protobuf
48103
--pretty Pretty-print JSON output (implies --json)
49104
--include-payload Include original JFR payload in OTLP output
105+
--diagnostics Show detailed diagnostics (file sizes, conversion time)
50106
--help Show this help message
51107
52108
Examples:
@@ -65,10 +121,14 @@ Examples:
65121
# Combine multiple JFR files
66122
$(basename "$0") file1.jfr file2.jfr combined.pb
67123
124+
# Show detailed diagnostics
125+
$(basename "$0") --diagnostics recording.jfr output.pb
126+
68127
Notes:
69128
- Uses Gradle's convertJfr task under the hood
70129
- Automatically compiles if needed
71130
- Output format is detected from extension (.pb or .json)
131+
- Use --diagnostics to see file sizes and conversion times
72132
73133
EOF
74134
}
@@ -79,24 +139,99 @@ if [ $# -eq 0 ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
79139
exit 0
80140
fi
81141

142+
# Check for diagnostics flag
143+
SHOW_DIAGNOSTICS=false
144+
CONVERTER_ARGS=()
145+
INPUT_FILES=()
146+
147+
while [[ $# -gt 0 ]]; do
148+
case $1 in
149+
--diagnostics)
150+
SHOW_DIAGNOSTICS=true
151+
shift
152+
;;
153+
--json|--pretty|--include-payload)
154+
CONVERTER_ARGS+=("$1")
155+
shift
156+
;;
157+
*)
158+
# Collect files
159+
CONVERTER_ARGS+=("$1")
160+
# If it's not the last arg and file exists, it's an input file
161+
if [ $# -gt 1 ] && [ -f "$1" ]; then
162+
INPUT_FILES+=("$1")
163+
fi
164+
shift
165+
;;
166+
esac
167+
done
168+
82169
# Convert all arguments to a space-separated string for Gradle --args
83-
ARGS="$*"
170+
ARGS="${CONVERTER_ARGS[*]}"
171+
172+
# Calculate total input size if diagnostics enabled
173+
TOTAL_INPUT_SIZE=0
174+
if [ "$SHOW_DIAGNOSTICS" = true ]; then
175+
for input_file in "${INPUT_FILES[@]}"; do
176+
if [ -f "$input_file" ]; then
177+
size=$(get_file_size_bytes "$input_file")
178+
TOTAL_INPUT_SIZE=$((TOTAL_INPUT_SIZE + size))
179+
log_diagnostic "Input: $input_file ($(format_bytes $size))"
180+
fi
181+
done
182+
if [ ${#INPUT_FILES[@]} -gt 0 ]; then
183+
log_diagnostic "Total input size: $(format_bytes $TOTAL_INPUT_SIZE)"
184+
fi
185+
fi
84186

85187
log_info "Converting JFR to OTLP format..."
86-
log_info "Arguments: $ARGS"
87188

88189
cd "$PROJECT_ROOT"
89190

191+
# Measure conversion time
192+
START_TIME=$(date +%s%N)
193+
START_CPU=$(ps -o cputime= -p $$ | tr -d ' :')
194+
90195
# Run Gradle task with arguments
91196
if ./gradlew -q :dd-java-agent:agent-profiling:profiling-otel:convertJfr --args="$ARGS"; then
197+
# Measure end time
198+
END_TIME=$(date +%s%N)
199+
END_CPU=$(ps -o cputime= -p $$ | tr -d ' :')
200+
92201
# Extract output file (last argument)
93-
OUTPUT_FILE="${!#}"
202+
OUTPUT_FILE="${CONVERTER_ARGS[-1]}"
94203

95204
log_success "Conversion completed successfully!"
96205

97206
if [ -f "$OUTPUT_FILE" ]; then
98-
SIZE=$(du -h "$OUTPUT_FILE" | cut -f1)
207+
OUTPUT_SIZE=$(get_file_size_bytes "$OUTPUT_FILE")
208+
SIZE=$(format_bytes $OUTPUT_SIZE)
99209
log_info "Output file: $OUTPUT_FILE ($SIZE)"
210+
211+
if [ "$SHOW_DIAGNOSTICS" = true ]; then
212+
echo ""
213+
log_diagnostic "=== Conversion Diagnostics ==="
214+
215+
# Calculate wall time
216+
WALL_TIME_NS=$((END_TIME - START_TIME))
217+
WALL_TIME_MS=$(awk "BEGIN {printf \"%.1f\", $WALL_TIME_NS/1000000}")
218+
log_diagnostic "Wall time: ${WALL_TIME_MS}ms"
219+
220+
# Show size comparison
221+
if [ ${#INPUT_FILES[@]} -gt 0 ]; then
222+
RATIO=$(calc_compression_ratio $TOTAL_INPUT_SIZE $OUTPUT_SIZE)
223+
log_diagnostic "Output size: $(format_bytes $OUTPUT_SIZE)"
224+
log_diagnostic "Size ratio: $RATIO of input"
225+
226+
if [ "$OUTPUT_SIZE" -lt "$TOTAL_INPUT_SIZE" ]; then
227+
SAVINGS=$((TOTAL_INPUT_SIZE - OUTPUT_SIZE))
228+
SAVINGS_PCT=$(awk "BEGIN {printf \"%.1f%%\", (1 - $OUTPUT_SIZE/$TOTAL_INPUT_SIZE) * 100}")
229+
log_diagnostic "Savings: $(format_bytes $SAVINGS) ($SAVINGS_PCT reduction)"
230+
fi
231+
fi
232+
233+
echo ""
234+
fi
100235
fi
101236
else
102237
EXIT_CODE=$?

dd-java-agent/agent-profiling/profiling-otel/doc/CLI.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ dd-java-agent/agent-profiling/profiling-otel/convert-jfr.sh
329329
- `--json` - Output in JSON format instead of protobuf
330330
- `--pretty` - Pretty-print JSON output (implies --json)
331331
- `--include-payload` - Include original JFR payload in OTLP output
332+
- `--diagnostics` - Show detailed diagnostics (file sizes, conversion time)
332333
- `--help` - Show help message
333334

334335
### Examples
@@ -358,12 +359,33 @@ Combine multiple files:
358359
./convert-jfr.sh file1.jfr file2.jfr file3.jfr merged.pb
359360
```
360361

362+
Show detailed diagnostics:
363+
```bash
364+
./convert-jfr.sh --diagnostics recording.jfr output.pb
365+
```
366+
367+
Output:
368+
```
369+
[INFO] Converting JFR to OTLP format...
370+
[DIAG] Input: recording.jfr (89.3KB)
371+
[DIAG] Total input size: 89.3KB
372+
[SUCCESS] Conversion completed successfully!
373+
[INFO] Output file: output.pb (45.2KB)
374+
375+
[DIAG] === Conversion Diagnostics ===
376+
[DIAG] Wall time: 127.3ms
377+
[DIAG] Output size: 45.2KB
378+
[DIAG] Size ratio: 50.6% of input
379+
[DIAG] Savings: 44.1KB (49.4% reduction)
380+
```
381+
361382
### Features
362383

363384
- **Automatic compilation**: Compiles code if needed before conversion
364385
- **Simplified interface**: No need to remember Gradle task paths
365386
- **Colored output**: Visual feedback for success/errors
366387
- **File size reporting**: Shows output file size after conversion
388+
- **Diagnostics mode**: Detailed metrics including input/output sizes, conversion time, and compression ratio
367389
- **Error handling**: Clear error messages if conversion fails
368390

369391
### Script Output

0 commit comments

Comments
 (0)