// Alerting with context: // // This example shows how to annotate an alert event with recent lines from // a logging stream, to give context for the alert. This is accomplished with // a custom reducer that tails the log stream, and a join of the current tail // against each alert event as it occurs. // // The log-tailing stream is joined using the -table option, which means the // join will fire only when the alert stream gets a new point, but not fire // when the log stream gets new points. // /////////////////////////////////////////////////////////////////////////////// // // simulated alert and logging streams // sub alerts() { emit -every :5s: -limit 3 | put event="alert" } sub logs() { emit -every :250ms: -limit 50 | put message="at "+Date.toString(time)+" the count was "+Number.toString(count()) } // // tail a field in a stream of points // reducer tail_field(field, N) { var context = []; var c_i = 0, c_n = 0; function update() { context[c_i] = *field; c_n = Math.min(c_n + 1, N); c_i = (c_i + 1) % N; } function get_tail(tail, j, c_j) { if (tail == null) { tail = []; j = 0; c_j = (c_i - c_n + N) % N; } if (j < c_n) { tail[j] = context[c_j]; return get_tail(tail, j + 1, (c_j + 1) % N); } else { return tail; } } function result() { return get_tail(null, null, null); } } // // Live stream demo: tap the alert and logging streams, and join them // whenever an alert fires. // ( alerts; logs | put context = tail_field('message', 5); )| join -table 2 | @table