feat(csv): change to csv from jsonl
This commit is contained in:
@@ -75,7 +75,7 @@ func (r *MeasurementRunner) runMeasurement(upstream string, domains []string, qT
|
||||
defer dnsClient.Close()
|
||||
|
||||
// Setup output files
|
||||
jsonPath, pcapPath := GenerateOutputPaths(r.config.OutputDir, upstream, r.config.DNSSEC, r.config.KeepAlive)
|
||||
csvPath, pcapPath := GenerateOutputPaths(r.config.OutputDir, upstream, r.config.DNSSEC, r.config.KeepAlive)
|
||||
|
||||
keepAliveStr := ""
|
||||
if r.config.KeepAlive {
|
||||
@@ -83,7 +83,7 @@ func (r *MeasurementRunner) runMeasurement(upstream string, domains []string, qT
|
||||
}
|
||||
|
||||
fmt.Printf(">>> Measuring %s (dnssec=%v%s) → %s\n", upstream, r.config.DNSSEC, keepAliveStr,
|
||||
strings.TrimSuffix(strings.TrimSuffix(jsonPath, ".jsonl"), r.config.OutputDir+"/"))
|
||||
strings.TrimSuffix(strings.TrimSuffix(csvPath, ".csv"), r.config.OutputDir+"/"))
|
||||
|
||||
// Setup packet capture
|
||||
packetCapture, err := capture.NewPacketCapture(r.config.Interface, pcapPath)
|
||||
@@ -93,7 +93,7 @@ func (r *MeasurementRunner) runMeasurement(upstream string, domains []string, qT
|
||||
defer packetCapture.Close()
|
||||
|
||||
// Setup results writer
|
||||
writer, err := results.NewMetricsWriter(jsonPath)
|
||||
writer, err := results.NewMetricsWriter(csvPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package results
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -23,29 +24,69 @@ type DNSMetric struct {
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// Rest stays exactly the same
|
||||
type MetricsWriter struct {
|
||||
encoder *json.Encoder
|
||||
file *os.File
|
||||
writer *csv.Writer
|
||||
file *os.File
|
||||
}
|
||||
|
||||
func NewMetricsWriter(path string) (*MetricsWriter, error) {
|
||||
file, err := os.Create(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create json output: %w", err)
|
||||
return nil, fmt.Errorf("create csv output: %w", err)
|
||||
}
|
||||
|
||||
writer := csv.NewWriter(file)
|
||||
|
||||
// Write CSV header
|
||||
header := []string{
|
||||
"domain", "query_type", "protocol", "dnssec", "keep_alive",
|
||||
"dns_server", "timestamp", "duration_ns", "duration_ms",
|
||||
"request_size_bytes", "response_size_bytes", "response_code", "error",
|
||||
}
|
||||
|
||||
if err := writer.Write(header); err != nil {
|
||||
file.Close()
|
||||
return nil, fmt.Errorf("write csv header: %w", err)
|
||||
}
|
||||
|
||||
writer.Flush()
|
||||
|
||||
return &MetricsWriter{
|
||||
encoder: json.NewEncoder(file),
|
||||
file: file,
|
||||
writer: writer,
|
||||
file: file,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (mw *MetricsWriter) WriteMetric(metric DNSMetric) error {
|
||||
return mw.encoder.Encode(metric)
|
||||
record := []string{
|
||||
metric.Domain,
|
||||
metric.QueryType,
|
||||
metric.Protocol,
|
||||
strconv.FormatBool(metric.DNSSEC),
|
||||
strconv.FormatBool(metric.KeepAlive),
|
||||
metric.DNSServer,
|
||||
metric.Timestamp.Format(time.RFC3339),
|
||||
strconv.FormatInt(metric.Duration, 10),
|
||||
strconv.FormatFloat(metric.DurationMs, 'f', 3, 64),
|
||||
strconv.Itoa(metric.RequestSize),
|
||||
strconv.Itoa(metric.ResponseSize),
|
||||
metric.ResponseCode,
|
||||
metric.Error,
|
||||
}
|
||||
|
||||
err := mw.writer.Write(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mw.writer.Flush()
|
||||
return mw.writer.Error()
|
||||
}
|
||||
|
||||
func (mw *MetricsWriter) Close() error {
|
||||
if mw.writer != nil {
|
||||
mw.writer.Flush()
|
||||
}
|
||||
if mw.file != nil {
|
||||
return mw.file.Close()
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func GenerateOutputPaths(outputDir, upstream string, dnssec, keepAlive bool) (jsonPath, pcapPath string) {
|
||||
func GenerateOutputPaths(outputDir, upstream string, dnssec, keepAlive bool) (csvPath, pcapPath string) {
|
||||
proto := DetectProtocol(upstream)
|
||||
serverName := ExtractServerName(upstream)
|
||||
ts := time.Now().Format("20060102_1504")
|
||||
@@ -18,8 +18,8 @@ func GenerateOutputPaths(outputDir, upstream string, dnssec, keepAlive bool) (js
|
||||
base := fmt.Sprintf("%s_%s_dnssec_%s_keepalive_%s_%s",
|
||||
proto, sanitize(serverName), dnssecStr, keepAliveStr, ts)
|
||||
|
||||
return filepath.Join(outputDir, base+".jsonl"),
|
||||
filepath.Join(outputDir, base+".pcap")
|
||||
return filepath.Join(outputDir, base+".csv"),
|
||||
filepath.Join(outputDir, base+".pcap")
|
||||
}
|
||||
|
||||
func sanitize(s string) string {
|
||||
|
||||
Reference in New Issue
Block a user