diff --git a/src/OnlineMonitor.cxx b/src/OnlineMonitor.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4d86b4f2413426b441b6c7b2ccb38e0ab7a83fb0
--- /dev/null
+++ b/src/OnlineMonitor.cxx
@@ -0,0 +1,133 @@
+#include "OnlineMonitor.h"
+#include "PRadETChannel.h"
+
+using namespace std::chrono;
+
+
+namespace hcana {
+
+Int_t OnlineMonitor::Monitor(PRadETChannel *ch, std::chrono::seconds interval)
+{
+    Int_t total = 0;
+    fMonitor = true;
+    static const char* const here = "Monitor";
+
+    fBench->Begin("Total");
+
+    void (*prev_handler)(int);
+    prev_handler = signal(SIGINT, handle_sig);
+
+    while (!fMonitor) {
+        system_clock::time_point start(system_clock::now());
+        system_clock::time_point next(start + interval);
+
+        total += ReadOnce(ch);
+        std::this_thread::sleep_until(next);
+    }
+
+    signal(SIGINT, prev_handler);
+
+    if (fDoBench)
+        fBench->Begin("Output");
+
+    if (fOutput && fOutput->GetTree()) {
+        fFile = fOutput->GetTree()->GetCurrentFile();
+    }
+    if (fFile)
+        fFile->cd();
+    if (fOutput)
+        fOutput->End();
+    if (fFile) {
+        fRun->Write("Run Data");
+        fFile->Purge();
+    }
+    if (fDoBench)
+        fBench->Stop("Output");
+
+    return total;
+}
+
+
+Int_t OnlineMonitor::ReadOnce(PRadETChannel *ch, size_t max_events)
+try {
+    Int_t count = 0;
+    for(size_t num = 0; ch->Read() && (num < max_events); ++num) {
+        auto buf = ch->GetBuffer();
+        count += ReadBuffer((uint32_t*)(ch->GetBuffer()));
+    }
+    return count;
+}
+catch (PRadException e) {
+    std::cerr << e.FailureType() << ": " << e.FailureDesc() << std::endl;
+    fMonitor = false;
+    return 0;
+}
+
+
+Int_t OnlineMonitor::ReadBuffer(uint32_t *buf)
+try {
+    switch (fEvData->LoadEvent(buf)) {
+    case THaEvData::HED_WARN:
+    case THaEvData::HED_OK:
+        break;
+    default:
+        return 0;
+    }
+
+    Int_t count = 0;
+    do {
+        count += ProcOneEvent();
+    } while ( fEvData->IsMultiBlockMode() &&
+              !fEvData->BlockIsDone() &&
+              (fEvData->LoadFromMultiBlock() == THaEvData::HED_OK) );
+
+    return count;
+}
+catch (...) {
+    throw;
+}
+
+Int_t OnlineMonitor::ProcOneEvent()
+{
+    UInt_t evnum = fEvData->GetEvNum();
+
+    switch (fCountMode) {
+    case kCountPhysics:
+        if (fEvData->IsPhysicsTrigger())
+            fNev++;
+        break;
+    case kCountAll:
+        fNev++;
+        break;
+    case kCountRaw:
+        fNev = evnum;
+        break;
+    default:
+        break;
+    }
+
+    if (fUpdateRun)
+        fRun->Update(fEvData);
+
+    if (fDoBench)
+        fBench->Begin("Cuts");
+    gHaCuts->ClearAll();
+    if (fDoBench)
+        fBench->Stop("Cuts");
+
+    switch (MainAnalysis()) {
+    case kOK:
+        return 1;
+    case kSkip:
+    default:
+        break;
+    case kTerminate:
+        throw(PRadException("Termination", "analysis is terminated."));
+    case kFatal:
+        throw(PRadException("Fatal Error", "analysis encountered fatal error."));
+    }
+
+    return 0;
+}
+
+} // namespace hcana
diff --git a/src/OnlineMonitor.h b/src/OnlineMonitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..738954777716ea346bae9da89de1bae7eff9b0b8
--- /dev/null
+++ b/src/OnlineMonitor.h
@@ -0,0 +1,32 @@
+#ifndef hcana_OnlineMonitor_h_
+#define hcana_OnlineMonitor_h_
+
+#include "THaBenchmark.h"
+#include "THcAnalyzer.h"
+#include <thread>
+#include <chrono>
+#include <iostream>
+
+
+class PRadETChannel;
+
+namespace hcana {
+
+    class OnlineMonitor : public THcAnalyzer {
+    public:
+        OnlineMonitor() : THcAnalyzer() {}
+        virtual ~OnlineMonitor() {}
+
+        virtual Int_t Monitor(PRadETChannel *ch, std::chrono::seconds interval = std::chrono::seconds(10));
+        virtual Int_t ReadOnce(PRadETChannel *ch, size_t max_events = 10000);
+        Int_t ReadBuffer(uint32_t *buf);
+        Int_t ProcOneEvent();
+        //Int_t GoToEndOfCodaFile();
+
+        ClassDef(OnlineMonitor, 0) // Hall C Analyzer Standard Event Loop
+    private:
+        bool fMonitor;
+    };
+
+} // namespace hcana
+#endif
diff --git a/src/Scandalizer.cxx b/src/Scandalizer.cxx
index 316929b416d96cfb4ec2274e4df63cfd65dc3407..5c2c1126d199de236acbce5297be655a00bce66b 100644
--- a/src/Scandalizer.cxx
+++ b/src/Scandalizer.cxx
@@ -7,8 +7,8 @@ namespace hcana {
 
 Int_t Scandalizer::ReadOneEvent()
 {
-  // Read one event from current run (fRun) and raw-decode it using the
-  // current decoder (fEvData)
+    // Read one event from current run (fRun) and raw-decode it using the
+    // current decoder (fEvData)
 
   if( fDoBench ) {fBench->Begin("RawDecode");}
 
diff --git a/src/Scandalizer.h b/src/Scandalizer.h
index f3e21e8c48c3514b350b0b61d5c0fbc2501a7e99..ab2a41d615eac4b4e263d9d2ed43c1d337668831 100644
--- a/src/Scandalizer.h
+++ b/src/Scandalizer.h
@@ -3,7 +3,6 @@
 
 #include "THaBenchmark.h"
 #include "THcAnalyzer.h"
-#include "PRadETChannel.h"
 #include <iostream>
 
 
@@ -17,13 +16,9 @@ namespace hcana {
     virtual Int_t Process(THaRunBase* run = nullptr);
     virtual Int_t ReadOneEvent();
     //Int_t GoToEndOfCodaFile();
-    void SetETChannel(PRadETChannel *ch) { online_ch = ch; }
-    PRadETChannel *GetETChannel() { return online_ch; }
 
     int _skip_events = 0;
 
-    PRadETChannel *online_ch;
-
     ClassDef(Scandalizer, 0) // Hall C Analyzer Standard Event Loop
   };
 
diff --git a/src/include/HallC_LinkDef.h b/src/include/HallC_LinkDef.h
index 7f859eb09523660dc57cdd59197fbcd05c5ff10d..4bc08c48e68dc47026b0ea6e37e2feed4084808c 100644
--- a/src/include/HallC_LinkDef.h
+++ b/src/include/HallC_LinkDef.h
@@ -93,5 +93,6 @@
 #pragma link C++ class hcana::Scandalizer+;
 #pragma link C++ class hcana::TrackingEfficiency+;
 
+#pragma link C++ class hcana::OnlineMonitor+;
 // Postamble for HallC_Linkdef.h file
 #endif