Warning, /swf-monitor/docs/OSG_SUBMIT_REPORTER.md is written in an unsupported language. File is not indexed.
0001 # OSG submit host reporter
0002
0003 A reporter on the OSG submit host (osgsub01) delivers the submission
0004 side of ePIC's OSG production to swf-monitor: what the pilots are
0005 allowed to land on, and what the pool currently offers them. It exists
0006 because that state is only knowable on that host. The submit
0007 description is the operative control over where pilots may run, and
0008 swf-monitor cannot read it: ssh to the submit host is refused except
0009 through the facility gateway with agent forwarding, so nothing on the
0010 monitor host can poll it. The reporter pushes instead.
0011
0012 Until it runs, the ePIC queues page renders the exclusions from a list
0013 declared in `swf_epicprod.osg_exclusions` and reconciled by hand with
0014 `swf-epicprod scripts/check-osg-exclusions.py`. That page labels those
0015 sections as declared rather than live, because a copy can be wrong.
0016 Replacing that label is the reporter's first purpose.
0017
0018 The agent is a standalone script in the house pattern — standard
0019 library only, local state file, periodic run, HTTPS delivery to a
0020 swf-monitor REST ingest under a per-host token — and it is read-only
0021 with respect to harvester, HTCondor, and the submit descriptions.
0022
0023 ## Functions
0024
0025 Each run posts one record; the account's cron runs it every two minutes.
0026
0027 | Function | Source on the host | Fields delivered |
0028 |---|---|---|
0029 | Exclusions in force | the submit description of each OSG queue | per queue: the excluded sites, the excluded site-and-node pairs parsed from the `Requirements` clause, the file's modification time |
0030 | Submission shape | the same files | requirements, resource requests, job duration category, pilot wrapper and its version |
0031 | Queue-to-file mapping | `/opt/harvester/etc/panda/panda_queueconfig.json` | which queue uses which submit description, worker limits, push or pull |
0032 | Pool admission | `condor_status` against the pool collectors | total slots; slots the queue's requirements admit; slots the exclusions remove, by site and node |
0033 | Pool composition | the same | slots per site, operating system, user-namespace and CVMFS availability |
0034 | Submission health | `condor_q` on the local schedd | workers idle, running and held per queue, with held reasons |
0035 | Idle pilots | `condor_q` and `condor_q -better-analyze` | per queue: idle pilots and the oldest one's age; for a queue with at least 100 idle, condor's match analysis of its oldest idle pilot (the pool's slots, those the pilot's requirements reject, those whose own requirements reject it, those willing, those that would match if drained, the last successful and failed match and the failure reason) |
0036 | Fair-share limit | `condor_status -pool <pool> -negotiator` for the schedd's collector and each pool it flocks to | per negotiator: the time of its last cycle and this schedd's submitters it held at their fair-share limit in that cycle; one small ad per negotiator |
0037
0038 A submitter held at its fair-share limit gets no new slots in that pool
0039 until its usage share falls, whatever the pool's free slots would
0040 accept; its running pilots keep their slots. On 24 October the OSPool
0041 negotiator held `atlpan@osgsub01.sdcc.bnl.gov` (priority factor 2,500)
0042 while free UChicago, IRISHEP and SU-ITS slots matched the waiting
0043 pilots in both directions, and pilots stopped reaching every site
0044 where they did not already hold slots.
0045
0046 The ingest compares each record's reading with the state kept in
0047 `PersistentState` (`monitor_app/osg_throttle.py`). A pool's first hold
0048 records one `osg_throttle` incident at info level, since the hold is
0049 OSG's normal mode of operation and never a warning on the dashboard's
0050 epicprod-live panel, which shows warnings and errors (Torre Wenaus,
0051 2026-10-28); its lift is
0052 recorded once the pool has released our submitter for three consecutive
0053 records, so a limit that flips between negotiation cycles is one
0054 incident. `#epicprod-live` carries both through its live subscription,
0055 and the `capcom` subscription (filter `state` held) delivers the hold
0056 to the operator's feed ([NOTICE_ROUTING.md](NOTICE_ROUTING.md)).
0057
0058 The schedd keeps about an hour and a half of job history and half an
0059 hour of its log, so a stall in pilot starts outlasts condor's own
0060 record of it. The reporter therefore also appends each run's idle
0061 analysis to `match-analysis.jsonl` in its state directory and keeps
0062 seven days of it on the host.
0063
0064 Every failure to read a source is delivered as a field, never dropped;
0065 an unreachable swf-monitor buffers records locally and posts the
0066 backlog on the next run. A silent reporter is visible as the record's
0067 age, which the page shows beside the exclusions.
0068
0069 ## Why the exclusions are worth reporting rather than declaring
0070
0071 A node exclusion names a site and a node together, because node names
0072 recur across sites: the pool advertises bare names such as `compute05`,
0073 `n358` and `fc20621` alongside fully qualified ones, and a name alone
0074 would ban a healthy machine elsewhere. That pairing is expressed in a
0075 `Requirements` clause, which is easy to write wrongly and impossible to
0076 verify from the monitor. Reporting it back closes the loop: the page
0077 shows what the submit host is actually enforcing, and disagreement with
0078 what anyone believes is enforced becomes visible rather than latent.
0079
0080 The pool-admission fields make the same point quantitatively. The
0081 exclusions are only meaningful against what the pool offers, and that
0082 changes daily; a count of slots removed is the measure of what an
0083 exclusion is doing today.
0084
0085 ## Access inventory
0086
0087 Verified on 2026-09-07 for the account that will run the reporter
0088 (uid `wenauseic`, group `eic`):
0089
0090 Available without additional privilege:
0091
0092 - Submit descriptions: `/var/data/atlpan/harvester_common/*.sdf`,
0093 world-readable, owned by `atlpan`.
0094 - Harvester queue configuration:
0095 `/opt/harvester/etc/panda/panda_queueconfig.json`, world-readable.
0096 - HTCondor client tools (`condor_q`, `condor_status`, version 25.0.12),
0097 giving the local schedd and the pool collectors.
0098 - Outbound HTTPS to swf-monitor on `pandaserver02.sdcc.bnl.gov`,
0099 verified at 13 ms.
0100 - Scheduling: cron is permitted for the account (`/etc/cron.deny` is
0101 empty, no `cron.allow`, no crontab today).
0102 - `/var` has 180 GB free; the root volume is 12 GB at 71 per cent, so
0103 state and buffer files live under `/var`.
0104
0105 Constraint worth stating because it is not obvious: the host's
0106 `python3` is 3.6.8. The reporter is written to that version and to the
0107 standard library alone, so it neither needs nor gets a virtual
0108 environment.
0109
0110 Privileged access: the account holds passwordless sudo. Nothing in the
0111 reporter's read path requires it. It is used at install only, to place
0112 a systemd unit if the cron form is replaced later.
0113
0114 ## Delivery
0115
0116 The reporter posts to `api/host-reports/<host>/` on swf-monitor,
0117 authenticated by a per-host token held in the reporter's environment
0118 file at mode 600. The ingest stores the record in the cached-product
0119 store under a key naming the host, so the record needs no table of its
0120 own: the store already holds a keyed JSON value with the time it was
0121 built, which is exactly a reporter's record and its freshness.
0122
0123 The ePIC queues page reads that record when it is present and falls
0124 back to the declared list when it is not, stating which of the two it
0125 is showing and how old it is.
0126
0127 ## Install
0128
0129 1. The script and its environment file on the submit host, mode 600 on
0130 the environment file.
0131 2. A cron entry for the account, on the reporting interval.
0132 3. The per-host token issued in swf-monitor.
0133
0134 No change to harvester, to HTCondor, or to any submit description is
0135 part of installing the reporter. Every install action on that host is
0136 announced and recorded in the action stream before it is taken.
0137
0138 ## Related
0139
0140 - [PANDA_SERVER_REPORTER.md](PANDA_SERVER_REPORTER.md) — the reporter
0141 on the PanDA server host, whose pattern this follows.
0142 - `swf-epicprod` `docs/OSG_SUBMISSION.md` — the submission path, the
0143 levers, and the exclusions this reports.
0144 - [CACHED_PRODUCTS.md](CACHED_PRODUCTS.md) — the store the record
0145 lands in.