improvements in robustness, save output of iperf3 for later analysis

This commit is contained in:
Jeffrey C. Ollie 2023-10-15 14:00:53 -05:00
parent 6ed252c5d7
commit aa9d8216d9
Signed by: jeff
GPG key ID: 6F86035A6D97044E

View file

@ -155,7 +155,10 @@ pub fn main() !void {
} }
while (true) { 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( var c = std.process.Child.init(
&[_][]const u8{ &[_][]const u8{
@ -166,33 +169,61 @@ pub fn main() !void {
"--json", "--json",
"--one-off", "--one-off",
}, },
allocator, arena.child_allocator,
); );
c.stdin_behavior = .Ignore; c.stdin_behavior = .Ignore;
c.stdout_behavior = .Pipe; c.stdout_behavior = .Pipe;
c.stderr_behavior = .Ignore; c.stderr_behavior = .Pipe;
try c.spawn(); try c.spawn();
var reader = c.stdout.?.reader(); var stdout = std.ArrayList(u8).init(arena.child_allocator);
var token_reader = std.json.reader(allocator, reader); 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, iperf3.IPerfReturn,
allocator, arena.child_allocator,
&token_reader, stdout.items,
.{}, .{},
); );
defer obj.deinit();
var line = std.ArrayList(u8).init(allocator); var level = loki.LogLevel.info;
try std.json.stringify( if (obj_or_err) |obj| {
obj.value, iperf3_log.info("successfully parsed json {d}", .{timestamp});
.{ if (obj.@"error") |err| {
.emit_null_optional_fields = false, iperf3_log.err("error from iperf3: {s}", .{err});
}, level = loki.LogLevel.@"error";
line.writer(), }
); } else |err| switch (err) {
defer line.deinit(); 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{ const streams = loki.LokiStreams{
.streams = &[_]loki.LokiStream{ .streams = &[_]loki.LokiStream{
@ -200,12 +231,12 @@ pub fn main() !void {
.stream = .{ .stream = .{
.job = "iperf3", .job = "iperf3",
.server = hostname, .server = hostname,
.level = if (obj.value.@"error" == null) .info else .@"error", .level = level,
}, },
.values = &[_]loki.LokiValue{ .values = &[_]loki.LokiValue{
.{ .{
.ts = std.time.nanoTimestamp(), .ts = timestamp,
.line = line.items, .line = stdout.items,
}, },
}, },
}, },
@ -238,13 +269,31 @@ pub fn main() !void {
var req = try client.request(.POST, uri, headers, .{}); var req = try client.request(.POST, uri, headers, .{});
defer req.deinit(); defer req.deinit();
iperf3_log.info("sending stream to loki", .{});
try req.start(); try req.start();
try req.writeAll(data.items); try req.writeAll(data.items);
try req.finish(); try req.finish();
try req.wait(); 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});
},
}
} }
} }