diff --git a/Modules/Core/Common/include/otbStandardOneLineFilterWatcher.h b/Modules/Core/Common/include/otbStandardOneLineFilterWatcher.h
index 9cbf761b4c12b5fec6f9309ee6ab38ddfe5cf0f8..8c3b6b47fe041c40a8b391310486478043d567b5 100644
--- a/Modules/Core/Common/include/otbStandardOneLineFilterWatcher.h
+++ b/Modules/Core/Common/include/otbStandardOneLineFilterWatcher.h
@@ -25,6 +25,7 @@
 #include <iosfwd>
 
 #include "otbFilterWatcherBase.h"
+#include "otbStandardOutputPrintCallback.h"
 
 namespace otb
 {
@@ -51,10 +52,10 @@ namespace otb
  *
  * \ingroup OTBCommon
  */
+template <class PrintCallbackType = StandardOutputPrintCallback>
 class OTBCommon_EXPORT StandardOneLineFilterWatcher : public FilterWatcherBase
 {
 public:
-
   /** Constructor. Takes a ProcessObject to monitor and an optional
    * comment string that is prepended to each event message. */
   StandardOneLineFilterWatcher(itk::ProcessObject* process,
@@ -66,6 +67,9 @@ public:
   /** Default constructor */
   StandardOneLineFilterWatcher();
 
+  /** Destrucotr */
+  virtual ~StandardOneLineFilterWatcher();
+
   /** Get/Set number of stars */
   void SetStars(int count)
   {
@@ -97,8 +101,16 @@ private:
   bool m_CoutIsConsole;
 
   std::string m_Buffer;
+  
+  PrintCallbackType * m_Callback;
+  
+  PrintCallbackType * m_DefaultCallback;
 };
 
 } // end namespace otb
 
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbStandardOneLineFilterWatcher.hxx"
+#endif
+
 #endif
diff --git a/Modules/Core/Common/src/otbStandardOneLineFilterWatcher.cxx b/Modules/Core/Common/include/otbStandardOneLineFilterWatcher.hxx
similarity index 67%
rename from Modules/Core/Common/src/otbStandardOneLineFilterWatcher.cxx
rename to Modules/Core/Common/include/otbStandardOneLineFilterWatcher.hxx
index f247061da6b4dca59baa48d8b4cf5bb9d7ac3ce8..129ccefa6bf4edc5c8863d936d9085a5d9c5e6bb 100644
--- a/Modules/Core/Common/src/otbStandardOneLineFilterWatcher.cxx
+++ b/Modules/Core/Common/include/otbStandardOneLineFilterWatcher.hxx
@@ -19,6 +19,9 @@
  * limitations under the License.
  */
 
+#ifndef otbStandardOneLineFilterWatcher_hxx
+#define otbStandardOneLineFilterWatcher_hxx
+
 #include <iostream>
 #include <sstream>
 
@@ -28,16 +31,19 @@
 
 namespace otb
 {
-
-StandardOneLineFilterWatcher
+template<class PrintCallbackType>
+StandardOneLineFilterWatcher<PrintCallbackType>
 ::StandardOneLineFilterWatcher()
   : m_StarsCount(50),
     m_CurrentNbStars(-1),
     m_CoutIsConsole( System::IsInteractive(1) )
 {
+  m_DefaultCallback = new PrintCallbackType;
+  m_Callback = m_DefaultCallback;
 }
 
-StandardOneLineFilterWatcher
+template<class PrintCallbackType>
+StandardOneLineFilterWatcher<PrintCallbackType>
 ::StandardOneLineFilterWatcher(itk::ProcessObject* process,
                         const char *comment)
   : FilterWatcherBase(process, comment),
@@ -45,9 +51,12 @@ StandardOneLineFilterWatcher
     m_CurrentNbStars(-1),
     m_CoutIsConsole( System::IsInteractive(1) )
 {
+  m_DefaultCallback = new PrintCallbackType;
+  m_Callback = m_DefaultCallback;
 }
 
-StandardOneLineFilterWatcher
+template<class PrintCallbackType>
+StandardOneLineFilterWatcher<PrintCallbackType>
 ::StandardOneLineFilterWatcher(itk::ProcessObject* process,
                         const std::string& comment)
   : FilterWatcherBase(process, comment.c_str()),
@@ -55,10 +64,20 @@ StandardOneLineFilterWatcher
     m_CurrentNbStars(-1),
     m_CoutIsConsole( System::IsInteractive(1) )
 {
+  m_DefaultCallback = new PrintCallbackType;
+  m_Callback = m_DefaultCallback;
 }
 
+template<class PrintCallbackType>
+StandardOneLineFilterWatcher<PrintCallbackType>
+::~StandardOneLineFilterWatcher()
+{
+  delete m_DefaultCallback;
+}
+
+template<class PrintCallbackType>
 void
-StandardOneLineFilterWatcher
+StandardOneLineFilterWatcher<PrintCallbackType>
 ::ShowProgress()
 {
   if (m_Process)
@@ -90,9 +109,10 @@ StandardOneLineFilterWatcher
       oss << m_Comment
           << ": "
           << progressPercent << "% [" << stars << blanks << "]";
-      if (m_CoutIsConsole)
+      if (m_Callback->IsInteractive())
         {
-        std::cout << "\r" << oss.str() << std::flush;
+        m_Callback->Call("\r" + oss.str());
+        m_Callback->Flush();
         }
       else
         {
@@ -104,29 +124,31 @@ StandardOneLineFilterWatcher
     }
 }
 
+template<class PrintCallbackType>
 void
-StandardOneLineFilterWatcher
+StandardOneLineFilterWatcher<PrintCallbackType>
 ::StartFilter()
 {
   m_Stopwatch.Start();
 }
 
+template<class PrintCallbackType>
 void
-StandardOneLineFilterWatcher
+StandardOneLineFilterWatcher<PrintCallbackType>
 ::EndFilter()
 {
   m_Stopwatch.Stop();
 
-  if (m_Process && !m_CoutIsConsole)
+  if (m_Process && !m_Callback->IsInteractive())
     {
-    std::cout << m_Buffer;
+    m_Callback->Call(m_Buffer);
     m_Buffer = std::string("");
     }
 
-  std::cout << " (";
-  m_Stopwatch.GetElapsedHumanReadableTime(std::cout);
-  std::cout << ")"
-            << std::endl;
+  m_Callback->Call(" (" + m_Stopwatch.GetElapsedHumanReadableTime() + ")\n");
+
 }
 
 } // end namespace otb
+
+#endif
diff --git a/Modules/Core/Common/include/otbStandardOutputPrintCallback.h b/Modules/Core/Common/include/otbStandardOutputPrintCallback.h
new file mode 100644
index 0000000000000000000000000000000000000000..bc5b39a9c4d123a42d6cc53371265cbc7423bbcd
--- /dev/null
+++ b/Modules/Core/Common/include/otbStandardOutputPrintCallback.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
+ *
+ * This file is part of Orfeo Toolbox
+ *
+ *     https://www.orfeo-toolbox.org/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef otbStandardOutputPrintCallback_h
+#define otbStandardOutputPrintCallback_h
+
+#include "otbSystem.h"
+
+namespace otb
+{
+
+/** \class StandardOutputPrintCallback
+ *  \brief Class with printing callback methods using the standard output
+ *
+ *  This class defines the Call method, used to write a string the standard 
+ *  output, the Flush method, used to flush it, and the IsInteractive 
+ *  method used to determine if the output is the console.
+ */
+
+class StandardOutputPrintCallback
+{
+public:
+  /** Constructor */
+  StandardOutputPrintCallback() :m_IsInteractive( System::IsInteractive(1)) {};
+
+  /** Destructor */
+  virtual ~StandardOutputPrintCallback() = default;
+
+  /** Write a string to a buffer */
+  void Call(std::string const& content);
+
+  /** Flush the buffer */
+  void Flush();
+
+  /** Determine if the output is interactive */
+  bool IsInteractive();
+  
+private:
+  /** flag determining if the output is interactive */
+  bool m_IsInteractive;
+};
+
+} // namespace otb
+
+#endif // otbStandardOutputPrintCallback_h
diff --git a/Modules/Core/Common/src/CMakeLists.txt b/Modules/Core/Common/src/CMakeLists.txt
index 91abc0b63f601f34421480cc33e3c12d6320f719..cfbef0afd4cc2b77b1e28995fb414d092ea4c68c 100644
--- a/Modules/Core/Common/src/CMakeLists.txt
+++ b/Modules/Core/Common/src/CMakeLists.txt
@@ -25,12 +25,12 @@ set(OTBCommon_SRC
   otbStandardWriterWatcher.cxx
   otbUtils.cxx
   otbConfigurationManager.cxx
-  otbStandardOneLineFilterWatcher.cxx
   otbWriterWatcherBase.cxx
   otbStopwatch.cxx
   otbStringToHTML.cxx
   otbExtendedFilenameHelper.cxx
   otbLogger.cxx
+  otbStandardOutputPrintCallback.cxx
   )
 
 add_library(OTBCommon ${OTBCommon_SRC})
diff --git a/Modules/Core/Common/src/otbStandardOutputPrintCallback.cxx b/Modules/Core/Common/src/otbStandardOutputPrintCallback.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2f41413405d42afcb0d4e372fcfb6f02698148ed
--- /dev/null
+++ b/Modules/Core/Common/src/otbStandardOutputPrintCallback.cxx
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
+ *
+ * This file is part of Orfeo Toolbox
+ *
+ *     https://www.orfeo-toolbox.org/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "otbStandardOutputPrintCallback.h"
+
+namespace otb
+{
+
+void
+StandardOutputPrintCallback
+::Call(std::string const& content)
+{
+  std::cout << content;
+}
+
+void
+StandardOutputPrintCallback
+::Flush()
+{
+  std::cout << std::flush;
+}
+
+bool
+StandardOutputPrintCallback
+::IsInteractive()
+{
+  return m_IsInteractive;
+}
+
+} // namespace otb
diff --git a/Modules/Core/Common/test/otbStandardOneLineFilterWatcherTest.cxx b/Modules/Core/Common/test/otbStandardOneLineFilterWatcherTest.cxx
index 5ef1f5eac1bde05480692300f210578910667dcc..dfd9bfcdac45585536754210927515941d98db77 100644
--- a/Modules/Core/Common/test/otbStandardOneLineFilterWatcherTest.cxx
+++ b/Modules/Core/Common/test/otbStandardOneLineFilterWatcherTest.cxx
@@ -38,7 +38,7 @@ int otbStandardOneLineFilterWatcherTest(int itkNotUsed(argc), char * argv[])
   typedef itk::GradientMagnitudeImageFilter<ImageType, ImageType> FilterType;
   FilterType::Pointer gradient = FilterType::New();
 
-  typedef otb::StandardOneLineFilterWatcher WatcherType;
+  typedef otb::StandardOneLineFilterWatcher<> WatcherType;
   WatcherType watcher1(gradient, "Gradient");
 
   gradient->SetInput(reader->GetOutput());
diff --git a/Modules/IO/IOGDAL/test/otbGDALOverviewsBuilder.cxx b/Modules/IO/IOGDAL/test/otbGDALOverviewsBuilder.cxx
index 4452cb65fc3c74273d773f5930c9ba1e5987a3e4..f250c83b96e0b9c32e1dec450357bd58d2369bda 100644
--- a/Modules/IO/IOGDAL/test/otbGDALOverviewsBuilder.cxx
+++ b/Modules/IO/IOGDAL/test/otbGDALOverviewsBuilder.cxx
@@ -42,7 +42,7 @@ int otbGDALOverviewsBuilder(int itkNotUsed(argc), char* argv[])
   filter->SetResamplingMethod(resamp);
 
   {
-    StandardOneLineFilterWatcher watcher(filter,"Overviews creation");
+    StandardOneLineFilterWatcher<> watcher(filter,"Overviews creation");
     filter->Update();
   }
 
diff --git a/Modules/Visualization/MonteverdiCore/src/mvdVectorImageModel.cxx b/Modules/Visualization/MonteverdiCore/src/mvdVectorImageModel.cxx
index 6470adfd61825a585696cb142d3a7c3252073d0c..24772864ba47f864dd127540874094d7b2f45435 100644
--- a/Modules/Visualization/MonteverdiCore/src/mvdVectorImageModel.cxx
+++ b/Modules/Visualization/MonteverdiCore/src/mvdVectorImageModel.cxx
@@ -260,7 +260,7 @@ VectorImageModel
 
   try
     {
-    otb::StandardOneLineFilterWatcher watcher(
+    otb::StandardOneLineFilterWatcher<> watcher(
       filter,
       ToStdString( tr( "Overviews creation: " ) )
     );
diff --git a/Modules/Wrappers/CommandLine/include/otbWrapperCommandLineLauncher.h b/Modules/Wrappers/CommandLine/include/otbWrapperCommandLineLauncher.h
index cc28ee8e9cd3b549e15f8a36005e67a06f644538..9e097a67cfafd11f96efc38867ea37e4b643d62b 100644
--- a/Modules/Wrappers/CommandLine/include/otbWrapperCommandLineLauncher.h
+++ b/Modules/Wrappers/CommandLine/include/otbWrapperCommandLineLauncher.h
@@ -76,7 +76,7 @@ public:
                  INVALIDNUMBEROFVALUE, DEFAULT} ParamResultType;
 
   /** Filter watcher list type */
-  typedef std::vector<StandardOneLineFilterWatcher *> WatcherListType;
+  typedef std::vector<StandardOneLineFilterWatcher<> *> WatcherListType;
 
   /** Command Member */
   typedef itk::MemberCommand< Self >        AddProcessCommandType;
diff --git a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
index bed8cd21dcbbfd8af0cf2cd0491151a2d7aa5a0e..a68201fa8f497ffdd086e9945cc6d010cb7be03a 100644
--- a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
+++ b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
@@ -596,7 +596,7 @@ void CommandLineLauncher::LinkWatchers(itk::Object * itkNotUsed(caller), const i
       {
       const AddProcessToWatchEvent* eventToWatch = dynamic_cast<const AddProcessToWatchEvent*> (&event);
 
-      StandardOneLineFilterWatcher * watch = new StandardOneLineFilterWatcher(eventToWatch->GetProcess(),
+      auto watch = new StandardOneLineFilterWatcher<>(eventToWatch->GetProcess(),
                                                                               eventToWatch->GetProcessDescription());
       m_WatcherList.push_back(watch);
       }