Class ChestLogService

java.lang.Object
com.enhancedechest.log.ChestLogService

public final class ChestLogService extends Object
Captures chest visits and persists each as one row (a contents snapshot + a change summary) in the separate ChestLogStore SQLite database, for the in-game /ee log viewer. Replaced the old plain-text audit logger.

One row per visit

A visit is opened, maybe changed, then closed. Only the close is written, and only when something actually changed — a visit that took or added nothing is never stored, so the database stays small (this is deliberate and not configurable). The stored snapshot is the chest as it was left; the diff is what moved while it was open, computed against the totals taken at open. Opening therefore does no disk work and no encoding at all: it just remembers when the chest was opened and what it held.

Where the work runs

The Bukkit-owned thread does the minimum: total the contents by material at open, and at close encode the contents to bytes once (ContainerCodec, the same immutable format chests are stored in) plus total them again for the diff. Both results are immutable, so they cross to the single writer thread with no Bukkit object. The writer batches inserts into one transaction and prunes on a timer. The queue is bounded, so a stalled disk drops the newest visits instead of growing the heap.
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final record 
    An encoded, thread-safe capture of a chest at close: bytes to store, totals to diff.
  • Constructor Summary

    Constructors
    Constructor
    Description
    ChestLogService(ContainerCodec codec, org.slf4j.Logger logger, Telemetry telemetry, ChestLogStore store, boolean storeReady, boolean enabled, int queueCapacity, int retentionDays, int maxPerPlayer, long pruneIntervalMillis)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    abandon(UUID actor, UUID owner, int index)
    Drops an open visit's baseline without writing, for a peek that changed nothing.
    capture(org.bukkit.inventory.ItemStack[] contents)
    Encodes and totals a chest's closing contents.
    void
    closed(@Nullable String actorName, UUID actor, UUID owner, int index, ChestLogService.Capture cap)
    Records a close from an already-taken capture, writing one row for the whole visit — but only if the contents actually changed.
    void
    closed(@Nullable String actorName, UUID actor, UUID owner, int index, org.bukkit.inventory.ItemStack[] contents)
    Records a close from live contents (captures, then delegates to the shared-capture overload).
    boolean
    Whether logging is on and running; a cheap volatile read callers use before building a snapshot.
    boolean
    needsCapture(boolean chestTouched)
    Whether the closing contents are worth capturing.
    void
    opened(@Nullable String actorName, UUID actor, UUID owner, int index, org.bukkit.inventory.ItemStack[] contents)
    Records the open baseline on the viewer's thread: when the chest was opened and what it held.
    void
    setEnabled(boolean enabled)
     
    void
    setRetention(int retentionDays, int maxPerPlayer, long pruneIntervalMillis)
     
    void
    Stops accepting visits, drains the queue, and joins the writer (≤5s).

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • ChestLogService

      public ChestLogService(ContainerCodec codec, org.slf4j.Logger logger, Telemetry telemetry, ChestLogStore store, boolean storeReady, boolean enabled, int queueCapacity, int retentionDays, int maxPerPlayer, long pruneIntervalMillis)
  • Method Details

    • setEnabled

      public void setEnabled(boolean enabled)
    • setRetention

      public void setRetention(int retentionDays, int maxPerPlayer, long pruneIntervalMillis)
    • isRecording

      public boolean isRecording()
      Whether logging is on and running; a cheap volatile read callers use before building a snapshot.
    • needsCapture

      public boolean needsCapture(boolean chestTouched)
      Whether the closing contents are worth capturing. A chest nobody clicked cannot have changed, so there is nothing to record on close. Mirrors the old logger's pre-filter so the session manager's call sites stay unchanged; a chest that was touched but ends up identical is still dropped by the exact diff at close.
    • capture

      @Nullable public @Nullable ChestLogService.Capture capture(org.bukkit.inventory.ItemStack[] contents)
      Encodes and totals a chest's closing contents. Returns null if encoding fails, so the caller simply skips logging that visit rather than aborting the chest operation.
    • opened

      public void opened(@Nullable @Nullable String actorName, UUID actor, UUID owner, int index, org.bukkit.inventory.ItemStack[] contents)
      Records the open baseline on the viewer's thread: when the chest was opened and what it held. No disk work and no encoding — the snapshot is only ever taken at close.
    • closed

      public void closed(@Nullable @Nullable String actorName, UUID actor, UUID owner, int index, org.bukkit.inventory.ItemStack[] contents)
      Records a close from live contents (captures, then delegates to the shared-capture overload).
    • closed

      public void closed(@Nullable @Nullable String actorName, UUID actor, UUID owner, int index, ChestLogService.Capture cap)
      Records a close from an already-taken capture, writing one row for the whole visit — but only if the contents actually changed. Force-close and shutdown tear down one shared inventory with several viewers; capturing once and passing it here keeps that O(1) in chest size.
    • abandon

      public void abandon(UUID actor, UUID owner, int index)
      Drops an open visit's baseline without writing, for a peek that changed nothing.
    • shutdown

      public void shutdown()
      Stops accepting visits, drains the queue, and joins the writer (≤5s).