The path a log line, a visit, a beacon report and a panel page take through the Loghound code, plus where configuration, state and the two indexes live. Written for a developer who has never seen the project.
A log line, into the hits index
Tailreads the new line and remembers its position inState.LogFormatandParserturn it into a request with named fields; lines that do not parse are sampled to a file.Enrich\Geo,Enrich\AsnandScore\Attacksadd context;ExclusionsandAttackPatternsapply the operator's rules.Sessionizerattaches the request to a visit (same network and browser, 30 minutes of inactivity closes it).Solr::addDocs()writes the batch into the hits index, afterQuotaconfirms there is room.
A visit, into the sessions index
loghound-scorefinds visits that went idle.Beacon::mergeIntoSession()adds what the browser reported.Score\Signalsgathers the evidence andScore\Rulescomputes the score, the verdict and its reasons.- The visit document, and the daily rollups, are written into the sessions index.
A beacon hit
b.jsin the visitor's browser posts tocollect.php.- The collector checks the signed token, size, origin and allowed hosts, rate-limits, stages the row in SQLite, and always answers 204. It never touches Solr.
- The next scorer run merges the staged row into its visit.
A panel page
public/index.phpsets security headers, loads the configuration, sends first-time visitors to the installer, and checks sign-in and CSRF.- The view named in
?v=is looked up inLayout::routes(); its controller draws the page frame without querying Solr. - Each card then asks the server for its own data (
?api=); the controller answers throughGateway,CacheandSolr, so one slow card never blocks the others. - On the browser side,
public/assets/js/app.jsloads the matching module frompublic/assets/js/views/, which fills its cards withloadCard()fromcore.js.
- The configuration is a PHP array in
config/loghound.php, mode 0640, written byConfig::save(). Its sections are documented inconfig/loghound.example.phpand on settings. - Secrets — the Opensolr API key, the beacon secret, the IP salt, the panel password hash and the two-factor secret — live in that file; sign-in state lives in files under
var/with mode 0600. None of them is ever committed. - Working state is
var/state.db(SQLite) and a few status files, also undervar/.
solr/hits/conf holds one document per request; solr/sessions/conf one per visit plus daily rollups. Every field is explained on the Solr schema. The schema rules are strict: fields are not stored unless needed, string fields carry no norms, one full-text catchall field (on by default, ingest.catchall) feeds the free-text search, and an undeclared field is silently ignored.
- Change
solr/hits/conf/schema.xmlorsolr/sessions/conf/schema.xml. - Run
bin/loghound-schema --checkto see what differs from the live index. - Run
bin/loghound-schema --applyto upload it. Operators do the same after upgrading.
For developers
- Project structure
- How data moves
- Changing the code