improvements in robustness, save output of iperf3 for later analysis
This commit is contained in:
parent
6ed252c5d7
commit
aa9d8216d9
1 changed files with 72 additions and 23 deletions
95
src/main.zig
95
src/main.zig
|
@ -155,7 +155,10 @@ pub fn main() !void {
|
|||
}
|
||||
|
||||
while (true) {
|
||||
iperf3_log.info("waiting for connection", .{});
|
||||
iperf3_log.info("starting new iperf3", .{});
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
var c = std.process.Child.init(
|
||||
&[_][]const u8{
|
||||
|
@ -166,33 +169,61 @@ pub fn main() !void {
|
|||
"--json",
|
||||
"--one-off",
|
||||
},
|
||||
allocator,
|
||||
arena.child_allocator,
|
||||
);
|
||||
c.stdin_behavior = .Ignore;
|
||||
c.stdout_behavior = .Pipe;
|
||||
c.stderr_behavior = .Ignore;
|
||||
c.stderr_behavior = .Pipe;
|
||||
try c.spawn();
|
||||
|
||||
var reader = c.stdout.?.reader();
|
||||
var token_reader = std.json.reader(allocator, reader);
|
||||
var stdout = std.ArrayList(u8).init(arena.child_allocator);
|
||||
var stderr = std.ArrayList(u8).init(arena.child_allocator);
|
||||
|
||||
var obj = try std.json.parseFromTokenSource(
|
||||
iperf3_log.info("waiting for data", .{});
|
||||
|
||||
try c.collectOutput(&stdout, &stderr, 16384);
|
||||
|
||||
var filename_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||
var filename: []u8 = undefined;
|
||||
var timestamp = std.time.nanoTimestamp();
|
||||
|
||||
filename = try std.fmt.bufPrint(&filename_buf, "/tmp/{d}-stdout.json", .{timestamp});
|
||||
try std.fs.cwd().writeFile(filename, stdout.items);
|
||||
|
||||
filename = try std.fmt.bufPrint(&filename_buf, "/tmp/{d}-stderr.json", .{timestamp});
|
||||
try std.fs.cwd().writeFile(filename, stderr.items);
|
||||
|
||||
// var token_reader = std.json.reader(allocator, reader);
|
||||
|
||||
var obj_or_err = std.json.parseFromSliceLeaky(
|
||||
iperf3.IPerfReturn,
|
||||
allocator,
|
||||
&token_reader,
|
||||
arena.child_allocator,
|
||||
stdout.items,
|
||||
.{},
|
||||
);
|
||||
defer obj.deinit();
|
||||
|
||||
var line = std.ArrayList(u8).init(allocator);
|
||||
try std.json.stringify(
|
||||
obj.value,
|
||||
.{
|
||||
.emit_null_optional_fields = false,
|
||||
},
|
||||
line.writer(),
|
||||
);
|
||||
defer line.deinit();
|
||||
var level = loki.LogLevel.info;
|
||||
if (obj_or_err) |obj| {
|
||||
iperf3_log.info("successfully parsed json {d}", .{timestamp});
|
||||
if (obj.@"error") |err| {
|
||||
iperf3_log.err("error from iperf3: {s}", .{err});
|
||||
level = loki.LogLevel.@"error";
|
||||
}
|
||||
} else |err| switch (err) {
|
||||
error.UnknownField => iperf3_log.err("unknown field parsing json {d}", .{timestamp}),
|
||||
error.UnexpectedEndOfInput => iperf3_log.err("unexpected end of input parsing json {d}", .{timestamp}),
|
||||
else => iperf3_log.err("other error while parsing json {} {d}", .{ err, timestamp }),
|
||||
}
|
||||
|
||||
// var line = std.ArrayList(u8).init(allocator);
|
||||
// try std.json.stringify(
|
||||
// obj.value,
|
||||
// .{
|
||||
// .emit_null_optional_fields = false,
|
||||
// },
|
||||
// line.writer(),
|
||||
// );
|
||||
// defer line.deinit();
|
||||
|
||||
const streams = loki.LokiStreams{
|
||||
.streams = &[_]loki.LokiStream{
|
||||
|
@ -200,12 +231,12 @@ pub fn main() !void {
|
|||
.stream = .{
|
||||
.job = "iperf3",
|
||||
.server = hostname,
|
||||
.level = if (obj.value.@"error" == null) .info else .@"error",
|
||||
.level = level,
|
||||
},
|
||||
.values = &[_]loki.LokiValue{
|
||||
.{
|
||||
.ts = std.time.nanoTimestamp(),
|
||||
.line = line.items,
|
||||
.ts = timestamp,
|
||||
.line = stdout.items,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -238,13 +269,31 @@ pub fn main() !void {
|
|||
var req = try client.request(.POST, uri, headers, .{});
|
||||
defer req.deinit();
|
||||
|
||||
iperf3_log.info("sending stream to loki", .{});
|
||||
|
||||
try req.start();
|
||||
try req.writeAll(data.items);
|
||||
try req.finish();
|
||||
try req.wait();
|
||||
|
||||
iperf3_log.info("{}\n", .{req.response.status});
|
||||
if (req.response.status == .no_content) {
|
||||
iperf3_log.info("successfully sent stream to loki", .{});
|
||||
} else {
|
||||
iperf3_log.info("response from loki: {}\n", .{req.response.status});
|
||||
}
|
||||
const term = try c.wait();
|
||||
|
||||
_ = try c.wait();
|
||||
switch (term) {
|
||||
.Exited => |value| {
|
||||
if (value == 0) {
|
||||
iperf3_log.info("iperf3 competed successfully", .{});
|
||||
} else {
|
||||
iperf3_log.info("iperf3 exited with error {d}", .{value});
|
||||
}
|
||||
},
|
||||
else => {
|
||||
iperf3_log.info("iperf3 terminated: {}", .{term});
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue