small pixel drawing of a pufferfish gore

internal/assets/status.tmpl

{{ template "header.tmpl" . }}

<div class="row">
  <div class="col-md-12">
    <h3>{{ baseName .Service.Name }}</h3>
    <table class="table">
      <tr>
        <th>Path</th>
        <th>Started</th>
        <th>Actions</th>
      </tr>
      <tr>
        <td><a href="#{{ .Service.Name }}">{{ .Service.Name }}</a></td>
        <td>{{ .Service.Started.Format "Mon Jan _2 15:04:05 MST 2006" }}</td>
        <td style="display: flex; flex-wrap: wrap; gap: 1em">
{{ if .Service.Stopped }}
          <form method="POST" action="/restart">
            <input type="hidden" name="xsrftoken" value="{{ .XsrfToken }}">
            <input type="hidden" name="path" value="{{ .Service.Name }}">
            <input type="hidden" name="supervise" value="once">
            <input type="submit" value="▶ run once">
          </form>

          <form method="POST" action="/restart">
            <input type="hidden" name="xsrftoken" value="{{ .XsrfToken }}">
            <input type="hidden" name="path" value="{{ .Service.Name }}">
            <input type="hidden" name="supervise" value="loop">
            <input type="submit" value="🔁 supervise (run in a loop)">
          </form>
{{ else }}
          <form method="POST" action="/stop">
            <input type="hidden" name="xsrftoken" value="{{ .XsrfToken }}">
            <input type="hidden" name="path" value="{{ .Service.Name }}">
            <input type="submit" value="❌ stop">
          </form>
{{ end }}
        </td>
      </tr>
    </table>

    {{ if (ne .Service.Diverted "") }}
    <p>
      Diverted: <code>{{ .Service.Diverted }}</code>
    </p>
    {{ end }}

    <h3>stdout <small><a href="/log?path={{ .Service.Name }}&stream=stdout">raw log</a></small></h3>
    <pre id="stdout"></pre>

    <h3>stderr <small><a href="/log?path={{ .Service.Name }}&stream=stderr">raw log</a></small></h3>
    <pre id="stderr"></pre>

    <h3>module info</h3>
    <pre>{{ .Service.ModuleInfo }}</pre>

  </div>
</div>

{{ template "footer.tmpl" . }}

<script>
    function newLogrotate(elt) {
      const maxLines = 101;
      var lines = 0;
      return function (e) {
        const line = e.data;
        const txt = elt.innerText + line + "\n";
        lines += line.split("\n").length;

        var toRemove = lines - maxLines;
        var i = 0;
        while (toRemove-- > 0) {
          i = txt.indexOf("\n", i) + 1;
          lines--;
        }
        elt.innerText = txt.slice(i);
      };
    }

    var stderr = new EventSource("/log?path={{ .Service.Name }}&stream=stderr", {
      withCredentials: true,
    })
    stderr.onmessage = newLogrotate(document.getElementById("stderr"));

    var stdout = new EventSource("/log?path={{ .Service.Name }}&stream=stdout", {
      withCredentials: true,
    })
    stdout.onmessage = newLogrotate(document.getElementById("stdout"));

    window.onbeforeunload = function() {
        stderr.close();
        stdout.close();
    };
</script>