Gladex Agent Logs

Agent run logs & app logs · env: prod · LAN-only investor surface

Overview
Run logs455 files, 11.8 MB
Latest run logrun-20260925-022932-53.log
Log directory/data/agent-logs
App log directory/opt/startup/prod/logs
Run logs (newest first, last 50)
FileSizeModified (UTC)
run-20260925-022932-53.log 72 KB 2026-09-25 00:32:59
run-20260925-012106-52.log 297 KB 2026-09-25 00:19:32
run-20260925-003542-51.log 153 KB 2026-09-24 23:11:06
run-20260924-234828-50.log 204 KB 2026-09-24 22:25:42
run-20260924-230237-49.log 303 KB 2026-09-24 21:38:28
run-20260924-222340-48.log 206 KB 2026-09-24 20:52:37
run-20260924-215353-47.log 146 KB 2026-09-24 20:13:40
run-20260924-210315-46.log 182 KB 2026-09-24 19:43:53
run-20260924-200755-45.log 181 KB 2026-09-24 18:53:15
run-20260924-192844-44.log 133 KB 2026-09-24 17:57:55
run-20260924-182059-43.log 227 KB 2026-09-24 17:18:44
run-20260924-164658-42.log 181 KB 2026-09-24 16:10:59
run-20260924-160206-41.log 101 KB 2026-09-24 14:36:58
run-20260924-153643-40.log 127 KB 2026-09-24 13:52:05
run-20260924-151001-39.log 130 KB 2026-09-24 13:26:43
run-20260924-144921-38.log 90 KB 2026-09-24 13:00:01
run-20260924-143001-37.log 63 KB 2026-09-24 12:39:21
run-20260924-141012-36.log 106 KB 2026-09-24 12:20:01
run-20260924-135151-35.log 75 KB 2026-09-24 12:00:12
run-20260924-133211-34.log 116 KB 2026-09-24 11:41:51
run-20260924-130932-33.log 67 KB 2026-09-24 11:22:11
run-20260924-115831-32.log 260 KB 2026-09-24 10:59:32
run-20260924-111405-31.log 117 KB 2026-09-24 09:48:31
run-20260924-102752-30.log 106 KB 2026-09-24 09:04:05
run-20260924-100538-29.log 81 KB 2026-09-24 08:17:52
run-20260924-092904-28.log 101 KB 2026-09-24 07:55:38
run-20260924-083526-27.log 116 KB 2026-09-24 07:19:04
run-20260924-080136-26.log 75 KB 2026-09-24 06:25:26
run-20260924-074910-25.log 23 KB 2026-09-24 05:51:36
run-20260924-072601-24.log 52 KB 2026-09-24 05:39:10
run-20260924-065657-23.log 156 KB 2026-09-24 05:16:01
run-20260924-063310-22.log 76 KB 2026-09-24 04:46:57
run-20260924-055309-21.log 107 KB 2026-09-24 04:23:10
run-20260924-052831-20.log 133 KB 2026-09-24 03:43:09
run-20260924-050107-19.log 69 KB 2026-09-24 03:18:31
run-20260924-044831-18.log 34 KB 2026-09-24 02:51:07
run-20260924-041948-17.log 156 KB 2026-09-24 02:38:31
run-20260924-035438-16.log 185 KB 2026-09-24 02:09:48
run-20260924-033002-15.log 245 KB 2026-09-24 01:44:38
run-20260924-025910-14.log 120 KB 2026-09-24 01:20:02
run-20260924-023430-13.log 97 KB 2026-09-24 00:49:10
run-20260924-015458-12.log 255 KB 2026-09-24 00:24:30
run-20260924-012751-11.log 179 KB 2026-09-23 23:44:58
run-20260924-005036-10.log 162 KB 2026-09-23 23:17:51
run-20260924-000545-9.log 217 KB 2026-09-23 22:40:36
run-20260923-235334-8.log 29 KB 2026-09-23 21:55:45
run-20260923-233751-7.log 97 KB 2026-09-23 21:43:34
run-20260923-231451-6.log 165 KB 2026-09-23 21:27:51
run-20260923-225120-5.log 58 KB 2026-09-23 21:04:51
run-20260923-222610-4.log 230 KB 2026-09-23 20:41:20
Tail — run-20260925-022932-53.log (last 200 lines)
-rw-r--r-- 1 root root    0 Sep 21 20:29 .gitkeep
$ cd /data/repo && timeout 300 ./tools/system-status --format human 2>&1 | tail -45; echo "EXIT=$?"
=== Gladex System Status ===

  investor-app-dev          [OK] active
  investor-app-prod         [OK] active
  git-daemon                [OK] active
  apache2                   [OK] active
  certbot-renew             [OK] active
  watchdog                  [OK] active
  healthz-dev               [OK] 200
  healthz-prod              [OK] 200
  download                  [OK] 200
  api-health                [OK] 200
  api-uptime                [OK] 200
  api-endpoints             [OK] 200
  api-changelog             [OK] 200
  api-stats                 [OK] 200
  DNS:gladex.de             [OK] 77.90.15.49
  DNS:dev.gladex.de         [OK] 77.90.15.49
  DNS:git.gladex.de         [OK] 77.90.15.49
  DNS:info.gladex.de        [OK] 77.90.15.49
  DNS:stats.gladex.de       [OK] 77.90.15.49
  DNS:team.gladex.de        [OK] 77.90.15.49
  DNS:log.gladex.de         [OK] 77.90.15.49
  MX:gladex.de              [OK] 10 gladex.de. on 1.1.1.1+8.8.8.8
  SOA:gladex.de             [WARN] serial=2026092402 consistent on 1.1.1.1+8.8.8.8; mname=placeholder (NEEDS-INVESTOR open)
  tls-cert-expiry           [OK] 88d left
  investor-messages         [OK] 0 unread dev=0 prod=0
  git-tree                  [OK] clean
  go-tests                  [OK] passing (worktree)
  go-compile                [OK] 45 module file(s) compile clean (1.644s) (commit e83aa62)
  promote-gates             [WARN] not promotable: verdict REFUSED: no verdict in /data/repo/mailboxes/reviewer-to-main (expected VERDICT-YYYYMMDD-HHMMSS-<slug>.md containing 'VERDICT: APPROVE') | dev-sync OK | commit-lint OK (commit e83aa62)

Overall: ALL SYSTEMS HEALTHY
EXIT=0
> build · mimo-v2.6-flash-free
$ cd /data/repo && grep -n "promote-gates\|go_compile\|divergence\|GATE_PROBE\|GLADEX_PROMOTE" tools/system-status | head -60
69:            echo "  ok 'compile clean'      go_compile.ok AND the child exited 0"
79:            echo "promote-gates verdicts (from promote-dev-to-prod --dry-run --force --format json):"
87:            echo "  The row runs the child with --dry-run AND GLADEX_GATE_PROBE=1: the"
90:            echo "Test hooks (env), promote-gates row:"
91:            echo "  GLADEX_PROMOTE_BIN      promote-dev-to-prod to query"
93:            echo "  GLADEX_PROMOTE_TIMEOUT  seconds the child is given (default: 120)"
386:# Go compile of the COMMIT — repo-lint's `go_compile` gate, carried onto the
398:# Contract (pinned by tests/test_system_status_go_compile.sh):
399:#   go_compile.ok true  AND child exit 0        -> ok
400:#   go_compile.ok true  AND child exit != 0     -> warning: a green row next
408:#   .go files, child error field, unparseable output, missing go_compile,
415:#   detail says so — that divergence (the fix is uncommitted) is the exact
461:gc = doc.get("go_compile")
463:    emit("warning", "cannot verify: repo-lint reported no go_compile object%s (exit %s)" % (": " + clean(err, 120) if err else "", rc))
537:# GLADEX_GATE_PROBE=1 pins it shut from the child's side as well: if either
551:#   and the divergence guard: the commit-lint gate and the go-compile row run
668:# Test hooks (env): GLADEX_PROMOTE_BIN (default: promote-dev-to-prod inside the
671:# promotion), GLADEX_PROMOTE_TIMEOUT (default 120). Both documented in --help.
672:PROMOTE_BIN="${GLADEX_PROMOTE_BIN:-$REPO_DIR/tools/promote-dev-to-prod}"
673:PROMOTE_TIMEOUT="${GLADEX_PROMOTE_TIMEOUT:-120}"
680:    PG_OUT=$(GLADEX_REPO_DIR="$REPO_DIR" GLADEX_GATE_PROBE=1 \
693:            PG_DETAIL="cannot verify: promote-gates row could not be parsed"
697:STATUS_ITEMS+=("{\"name\":\"promote-gates\",\"status\":\"$PG_STATUS\",\"detail\":\"$PG_DETAIL\"}")
$ cd /data/repo && wc -l tools/system-status tests/*.sh | tail -50
739 tools/system-status
   322 tests/test_budget_show.sh
   249 tests/test_dns_verify.sh
   502 tests/test_domain_availability.sh
   152 tests/test_identity_wrapper.sh
   632 tests/test_ip_drift_check.sh
   433 tests/test_ip_drift_cron.sh
   751 tests/test_pdns_api.sh
   441 tests/test_promote_gate.sh
   516 tests/test_promote_json.sh
   438 tests/test_promote_lint_gate.sh
   761 tests/test_repo_lint.sh
   272 tests/test_smtp_relay_probe.sh
   208 tests/test_source_sync_check.sh
   509 tests/test_system_status_go_compile.sh
   570 tests/test_system_status_go_tests.sh
   278 tests/test_system_status_mx_soa.sh
   581 tests/test_system_status_promote_gates.sh
   233 tests/test_system_status_unread.sh
   466 tests/test_tls_check.sh
  9053 total
> build · mimo-v2.6-flash-free
→ Read repo/tools/system-status [offset=520, limit=220]
> build · mimo-v2.6-flash-free
$ cd /data/repo && grep -n "GATE_REPORT\|_record_gate\|_build_report\|def promote\|def _promote\|dry_run\|\"sha\"\|sha =" tools/promote-dev-to-prod | head -80
113:GATE_REPORT: List[Dict] = []
116:def _record_gate(name: str, code: int, detail: str) -> None:
118:    GATE_REPORT.append({
133:def run_cmd(cmd: list, cwd: str = None, dry_run: bool = False) -> Tuple[int, str, str]:
135:    if dry_run:
255:        _record_gate("verdict", EXIT_GATE, reason)
269:        _record_gate("verdict", EXIT_GATE, reason)
284:        _record_gate("verdict", EXIT_GATE, reason)
296:    _record_gate("verdict", 0, ok_detail)
316:        _record_gate("dev-sync", EXIT_DEVSYNC, reason)
334:        _record_gate("dev-sync", EXIT_DEVSYNC, reason)
344:        _record_gate("dev-sync", 0, ok_detail)
369:    _record_gate("dev-sync", EXIT_DEVSYNC, detail)
405:        _record_gate("commit-lint", EXIT_LINT, reason)
441:        _record_gate("commit-lint", 0, ok_detail)
506:    sha = (res.stdout or "").strip()
512:def _build_report(dry_run: bool, force: bool, rc: Optional[int],
515:    gates = list(GATE_REPORT)
525:        "dry_run": bool(dry_run),
531:        "sha": sha,
532:        "performed": (rc == 0 and not dry_run),
537:def promote(dry_run: bool = False, force: bool = False, fmt: str = "human") -> int:
549:    GATE_REPORT.clear()
550:    sha = _head_sha(repo_root) if fmt == "json" else None
558:        rc = _promote(dry_run, force, repo_root, dev_root, prod_root)
562:            report = _build_report(dry_run, force, rc, sha)
567:def _promote(dry_run: bool, force: bool, repo_root: str, dev_root: str,
596:    code, out, err = run_cmd(["git", "status", "--porcelain"], cwd=repo_root, dry_run=dry_run)
600:    if out.strip() and not dry_run:
605:    code, commit_hash, err = run_cmd(["git", "rev-parse", "HEAD"], cwd=repo_root, dry_run=dry_run)
626:            code, out, err = run_cmd(["rsync", "-av", "--delete", repo_src + "/", prod_src + "/"], dry_run=dry_run)
639:        code, out, err = run_cmd(["composer", "install", "--no-dev", "--optimize-autoloader"], cwd=prod_src, dry_run=dry_run)
648:        code, out, err = run_cmd(["bash", "seed.sh"], cwd=prod_root, dry_run=dry_run)
655:    code, out, err = run_cmd(["systemctl", "restart", "investor-app-prod.service"], dry_run=dry_run)
661:    if not dry_run:
666:    code, out, err = run_cmd([os.path.join(repo_root, "tools", "healthcheck"), "prod", "--format", "json"], dry_run=dry_run)
709:    dry_run      whether the mutating phase was suppressed (assert this)
767:        args.dry_run = True
769:    sys.exit(promote(dry_run=args.dry_run, force=args.force, fmt=args.format))
→ Read repo/tools/system-status [offset=386, limit=135]
> build · mimo-v2.6-flash-free
$ cd /data/repo && grep -n "same child\|sha\|sha_resolved\|go-compile\|SS_GCC" tests/test_system_status_promote_gates.sh | head -60
22:#   * DIVERGENCE guard: the commit-lint gate and the go-compile row run the
23:#     same repo-lint on the same sha, so a contradiction between them is
32:#   * GLADEX_REPO_LINT_BIN points at the repo-lint scenario stub (the go-compile
95:# Scenario repo-lint for the INDEPENDENT go-compile row (the divergence guard
103:    body='{"tool":"repo-lint","requested_sha":"HEAD","sha_resolved":"abc1234deadbeefcafe000000000000000000001","error":null,"files_total":163,"linted":{"go":43},"skipped":{},"failures":[],"errors":[],"go_compile":{"attempted":true,"go_mod":"app/src/go/go.mod","files":45,"ok":true,"reason":null,"summary":"45 module file(s) compile clean (1.647s)","duration_s":1.647},"ok":true,"exit_code":0}'
107:    body='{"tool":"repo-lint","requested_sha":"HEAD","sha_resolved":"abc1234deadbeefcafe000000000000000000001","error":null,"files_total":163,"linted":{"go":43},"skipped":{},"failures":[],"errors":[{"path":"tools/repo-lint","lang":"python","error":"git timed out after 10s"}],"go_compile":{"attempted":true,"go_mod":"app/src/go/go.mod","files":45,"ok":true,"reason":null,"summary":"45 module file(s) compile clean (1.612s)","duration_s":1.612},"ok":false,"exit_code":3}'
109:  # THE COMMIT IS BROKEN -> go-compile row is `error`.
111:    body='{"tool":"repo-lint","requested_sha":"HEAD","sha_resolved":"abc1234deadbeefcafe000000000000000000001","error":null,"files_total":163,"linted":{"go":43},"skipped":{},"failures":[{"path":"app/src/go/cmd/gladex/commands/status_test.go","lang":"go-compile","line":5,"message":"package json is not in std"}],"errors":[],"go_compile":{"attempted":true,"go_mod":"app/src/go/go.mod","files":45,"ok":false,"reason":null,"summary":"1 compile error(s) in committed file(s) (0.51s)","duration_s":0.51},"ok":false,"exit_code":1}'
143:def emit(gates, ready, blocked, dry_run=True, sha="abc1234deadbeef",
148:           "sha": sha, "performed": False, "exit_code": rc}
178:         False, ["verdict"], sha=None)
286:echo "=== 4. commit-lint refuses while go-compile can only warn -> no divergence ==="
293:assert_not_contains "a non-claiming go-compile row is NOT divergence" "disagree" "$DETAIL"
342:echo "=== 10. output we cannot read -> cannot verify (three shapes) ==="
382:echo "=== 14. DIVERGENCE: the gate and the go-compile row contradict ==="
390:assert_contains "it points at the same child and sha" "same child, same sha" "$DETAIL"
414:# go-compile green (RL_MODE) so ONLY the promote row can move the verdict:
430:assert_contains "--help still documents the go-compile row" "go-compile verdicts" "$HELP"
537:  # go-compile must be GREEN here, or the divergence guard (correctly) fires on
$ cd /data/repo && sed -n '495,545p' tools/promote-dev-to-prod
def _head_sha(repo_root: str) -> Optional[str]:
    """Short HEAD of the repo we would promote, or None. Read-only git query
    (never short-circuited by --dry-run: it resolves nothing and changes
    nothing), so the JSON report can carry the same provenance the dashboard's
    other commit-side rows carry."""
    try:
        res = subprocess.run(["git", "-C", repo_root, "rev-parse", "--short", "HEAD"],
                             capture_output=True, text=True, timeout=5)
    except Exception:
        return None
    sha = (res.stdout or "").strip()
    if res.returncode == 0 and sha:
        return sha[:12]
    return None


def _build_report(dry_run: bool, force: bool, rc: Optional[int],
                  sha: Optional[str]) -> Dict:
    """The one machine-readable object --format json prints on stdout."""
    gates = list(GATE_REPORT)
    blocked = [g["name"] for g in gates if g.get("code") != 0]
    expected = ["verdict", "dev-sync", "commit-lint"]
    evaluated = [g.get("name") for g in gates]
    ready = (not blocked
             and all(name in evaluated for name in expected)
             and rc == 0)
    return {
        "tool": "promote-dev-to-prod",
        "timestamp": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
        "dry_run": bool(dry_run),
        "force": bool(force),
        "probe": os.environ.get("GLADEX_GATE_PROBE") == "1",
        "gates": gates,
        "ready": ready,
        "blocked_by": blocked,
        "sha": sha,
        "performed": (rc == 0 and not dry_run),
        "exit_code": rc,
    }


def promote(dry_run: bool = False, force: bool = False, fmt: str = "human") -> int:
    """Promote dev to prod, optionally emitting a machine-readable gate report.

    `--format json` prints EXACTLY ONE JSON object on stdout: every human line
    the gates print is rerouted to stderr, so a caller can `json.loads(stdout)`
    without filtering. The report is emitted on every path — early gate
    refusal included (a caller that gets no report learns nothing).
    """
    repo_root = os.environ.get("GLADEX_REPO_DIR", "/data/repo")

Select another run log from the list above. Only files matching run-YYYYMMDD-HHMMSS-N.log are readable.

App log tail — prod-8001.log (last 60 lines)
[Fri Sep 25 02:14:13 2026] 127.0.0.1:54028 Accepted
[Fri Sep 25 02:14:13 2026] 127.0.0.1:54028 Closing
[Fri Sep 25 02:14:13 2026] 127.0.0.1:54044 Accepted
[Fri Sep 25 02:14:13 2026] 127.0.0.1:54044 Closing
[Fri Sep 25 02:14:13 2026] 127.0.0.1:54058 Accepted
[Fri Sep 25 02:14:13 2026] 127.0.0.1:54058 Closing
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54074 Accepted
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54074 Closing
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54090 Accepted
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54090 Closing
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54102 Accepted
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54102 Closing
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54110 Accepted
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54110 Closing
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54120 Accepted
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54120 Closing
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54136 Accepted
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54136 Closing
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54144 Accepted
[Fri Sep 25 02:14:14 2026] 127.0.0.1:54144 Closing
[Fri Sep 25 02:14:14 2026] 127.0.0.1:37196 Accepted
[Fri Sep 25 02:14:14 2026] 127.0.0.1:37196 Closing
[Fri Sep 25 02:16:13 2026] 127.0.0.1:40870 Accepted
[Fri Sep 25 02:16:13 2026] 127.0.0.1:40870 Closing
[Fri Sep 25 02:16:14 2026] 127.0.0.1:40884 Accepted
[Fri Sep 25 02:16:14 2026] 127.0.0.1:40884 Closing
[Fri Sep 25 02:17:07 2026] 127.0.0.1:35328 Accepted
[Fri Sep 25 02:17:07 2026] 127.0.0.1:35328 Closing
[Fri Sep 25 02:18:44 2026] 127.0.0.1:33144 Accepted
[Fri Sep 25 02:18:44 2026] 127.0.0.1:33144 Closing
[Fri Sep 25 02:18:44 2026] 127.0.0.1:33152 Accepted
[Fri Sep 25 02:18:44 2026] 127.0.0.1:33152 Closing
[Fri Sep 25 02:18:44 2026] 127.0.0.1:51458 Accepted
[Fri Sep 25 02:18:44 2026] 127.0.0.1:51458 Closing
[Fri Sep 25 02:18:44 2026] 127.0.0.1:51460 Accepted
[Fri Sep 25 02:18:44 2026] 127.0.0.1:51460 Closing
[Fri Sep 25 02:18:44 2026] 127.0.0.1:51470 Accepted
[Fri Sep 25 02:18:44 2026] 127.0.0.1:51470 Closing
[Fri Sep 25 02:18:44 2026] 127.0.0.1:51482 Accepted
[Fri Sep 25 02:18:44 2026] 127.0.0.1:51482 Closing
[Fri Sep 25 02:18:44 2026] 127.0.0.1:51484 Accepted
[Fri Sep 25 02:18:45 2026] 127.0.0.1:51484 Closing
[Fri Sep 25 02:30:39 2026] 127.0.0.1:35084 Accepted
[Fri Sep 25 02:30:39 2026] 127.0.0.1:35084 Closing
[Fri Sep 25 02:30:39 2026] 127.0.0.1:35094 Accepted
[Fri Sep 25 02:30:39 2026] 127.0.0.1:35094 Closing
[Fri Sep 25 02:30:39 2026] 127.0.0.1:35110 Accepted
[Fri Sep 25 02:30:39 2026] 127.0.0.1:35110 Closing
[Fri Sep 25 02:30:39 2026] 127.0.0.1:35126 Accepted
[Fri Sep 25 02:30:39 2026] 127.0.0.1:35126 Closing
[Fri Sep 25 02:30:39 2026] 127.0.0.1:35132 Accepted
[Fri Sep 25 02:30:39 2026] 127.0.0.1:35132 Closing
[Fri Sep 25 02:30:39 2026] 127.0.0.1:35142 Accepted
[Fri Sep 25 02:30:39 2026] 127.0.0.1:35142 Closing
[Fri Sep 25 02:30:39 2026] 127.0.0.1:35150 Accepted
[Fri Sep 25 02:30:40 2026] 127.0.0.1:35150 Closing
[Fri Sep 25 02:33:01 2026] 127.0.0.1:57450 Accepted
[Fri Sep 25 02:33:01 2026] 127.0.0.1:57450 Closing
[Fri Sep 25 02:33:01 2026] 127.0.0.1:57464 Accepted

Generated 2026-09-25 00:33:01 UTC · Gladex.de