WIP: prototype for logging aggregation of output views and counts. #1460
Draft
cfkoehler wants to merge 1 commit into
Draft
WIP: prototype for logging aggregation of output views and counts. #1460cfkoehler wants to merge 1 commit into
cfkoehler wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add drop-off view-count stats (
placeStatsfor output)Motivation
When someone changes the drop-off/output config (
OUTPUT_TYPE/DENYLIST) that controls which views get written, there's currently no way to see the effect at runtime — you either diff output files by hand or wait for a downstream consumer to notice. This adds an always-available, low-overhead counter that answers "in the last N minutes, how many objects had view X written, broken down by file type and status?" — for live verification of drop-off config changes.It mirrors the existing
placeStats/ResourceWatcherpattern: accumulate counts in memory, flush an aggregated summary to a dedicated logfile on an interval, then reset — so each line is a rolling window.What it does
A new Namespace-bound singleton,
emissary.output.stats.ViewOutputStats, accumulates counts keyed byviewName × fileType × statusand a daemon scheduler flushes-and-resets them to a dedicateddropOffStatslogfile every interval. Each flush emits one structured (Logstash JSON) line per non-zero key:{"node":"localhost","viewName":"NormalizedText","fileType":"PDF","status":"OK","count":42,"windowSeconds":60}Hooks are wired into the framework's default output filters so it works out of the box:
DataFilter(raw output) — records each view withOK/WRITE_FAILEDwhen written, andNOT_OUTPUTTABLEfor views present but suppressed by config (the key config-verification signal, sinceDataFiltergates per-view).AbstractRollableFilter(JsonOutputFilter,XmlOutputFilter) — records each output object's primary view + non-empty alternate views asOK. These filters gate at the object level (all views or none), so there's noNOT_OUTPUTTABLEbreakdown on this path.The API is deliberately schema-agnostic (
record(viewName, fileType, status)takes plain strings), so downstream projects can feed their own view names and statuses without emissary depending on their types.Enablement
Off by default. Enable with env var
LOG_DROPOFF_STATS=true, which both wires up the aggregator (EmissaryNode) and enables the logback file appender. Flush cadence is configured inemissary/output/stats/ViewOutputStats.cfg(INTERVAL,INTERVAL_UNIT; currently1 MINUTE). When disabled,ViewOutputStats.record(...)is a cheap no-op (singleton not bound).Files
emissary/output/stats/ViewOutputStats.java,ViewOutputStats.cfg,ViewOutputStatsTest.javadirectory/EmissaryNode.java— create/bind when enabledserver/EmissaryServer.java— final flush + shutdown alongsideResourceWatcheroutput/filter/DataFilter.java,output/filter/AbstractRollableFilter.java— counting hooksconfig/logback.xml—dropOffStatsappender + logger (mirrorsobjectTrace)How to test / evaluate
INFO emissary.directory.EmissaryNode - Started drop-off view stats...ViewOutputStats flushing every 1 MINUTEStarget/data/InputData/, wait ≤1 minute.${emissary.output.root}/dropOffStats/<node>-<port>-dropoff-stats.log— expect one JSON line perviewName × fileType × statuswindow.OUTPUT_TYPE/DENYLISTentry for the active filter and confirm the next window shows counts move betweenOKandNOT_OUTPUTTABLE(on theDataFilterpath).Unit coverage:
ViewOutputStatsTest(accumulation, flush-and-reset window, concurrent counting with exact totals, no-op-when-unbound, lifecycle);DataFilterTest#testViewOutputStatsRecordedandJsonOutputFilterTest#testViewOutputStatsRecordeddrive the hooks end-to-end.Notes
objectTrace).AI Disclosure
LOG_DROPOFF_STATSand off by default