From 5ffd625a2baa072c31be7740b057ef68fbc4ff3b Mon Sep 17 00:00:00 2001
From: Ingo Ruhnke <grumbel@gmx.de>
Date: Wed, 26 Jan 2011 20:09:15 +0100
Subject: [PATCH] Rewrote logger

---
 src/chatpad.cpp                     | 25 +++++-----
 src/controller_slot_config.hpp      |  2 +
 src/evdev_helper.cpp                |  4 +-
 src/linux_uinput.cpp                | 31 ++++++------
 src/log.cpp                         | 43 ++++++++++++++++
 src/log.hpp                         | 76 ++++++++++++++++++++++++-----
 src/uinput.cpp                      |  4 +-
 src/uinput_message_processor.cpp    |  2 +-
 src/usb_read_thread.cpp             |  2 +-
 src/xbox360_controller.cpp          | 42 ++++++----------
 src/xbox360_wireless_controller.cpp | 20 ++++----
 src/xbox_controller.cpp             | 12 ++---
 src/xboxdrv_daemon.cpp              | 37 +++++++-------
 src/xboxdrv_thread.cpp              | 15 +++---
 14 files changed, 201 insertions(+), 114 deletions(-)

diff --git a/src/chatpad.cpp b/src/chatpad.cpp
index 7a5091b..6bc2c74 100644
--- a/src/chatpad.cpp
+++ b/src/chatpad.cpp
@@ -19,6 +19,7 @@
 #include "chatpad.hpp"
 
 #include <boost/format.hpp>
+#include <iostream>
 
 #include "linux_uinput.hpp"
 #include "log.hpp"
@@ -218,16 +219,18 @@ Chatpad::read_thread()
       }
       else
       {
-        if (m_debug)
+        if (g_logger.get_log_level() > Logger::kDebug)
         {
-          log_info << "read: " << len << "/5: data: " << std::flush;
+          std::ostringstream str;
+          str << "read: " << len << "/5: data: ";
           for(int i = 0; i < len; ++i)
           {
-            log_info << boost::format("0x%02x ") % int(data[i]);
+            str << boost::format("0x%02x ") % int(data[i]);
           }
-          log_info << std::endl;
-        }
 
+          log_debug(str);
+        }
+        
         if (data[0] == 0x00)
         {
           struct ChatpadKeyMsg msg;
@@ -239,7 +242,7 @@ Chatpad::read_thread()
   }
   catch(const std::exception& err)
   {
-    log_error << err.what() << std::endl;
+    log_error(err.what());
   }
 }
 
@@ -311,7 +314,7 @@ Chatpad::keep_alive_thread()
   }
   catch(const std::exception& err)
   {
-    log_error << err.what() << std::endl;
+    log_error(err.what());
   }
 }
 
@@ -366,10 +369,10 @@ Chatpad::send_init()
       if (m_debug) std::cout << "[chatpad] ret: " << usb_strerror(ret) << " " << static_cast<int>(buf[0]) << " " << static_cast<int>(buf[1]) << std::endl;
 
       /* FIXME: not proper way to check if the chatpad is alive
-      if (!(buf[1] & 2)) // FIXME: check for {9,0} for bcdDevice==0x114
-      {
-        throw std::runtime_error("chatpad init failure");
-      }
+         if (!(buf[1] & 2)) // FIXME: check for {9,0} for bcdDevice==0x114
+         {
+         throw std::runtime_error("chatpad init failure");
+         }
       */
       // chatpad is enabled, so start with keep alive
     }
diff --git a/src/controller_slot_config.hpp b/src/controller_slot_config.hpp
index 3f9d635..09c74b6 100644
--- a/src/controller_slot_config.hpp
+++ b/src/controller_slot_config.hpp
@@ -53,6 +53,8 @@ public:
   void next_config();
   void prev_config();
   int  config_count() const;
+  int get_current_config() const { return m_current_config; }
+
   ControllerConfigPtr get_config(int i) const;
   ControllerConfigPtr get_config() const;
 
diff --git a/src/evdev_helper.cpp b/src/evdev_helper.cpp
index 9f8435c..a5bdbdf 100644
--- a/src/evdev_helper.cpp
+++ b/src/evdev_helper.cpp
@@ -52,7 +52,7 @@ X11KeysymEnum::X11KeysymEnum() :
   Display* dpy = XOpenDisplay(NULL);
   if (!dpy)
   {
-    log_error << "unable to open X11 display, X11 keynames will not be available" << std::endl;
+    log_error("unable to open X11 display, X11 keynames will not be available");
   }
   else
   {
@@ -87,7 +87,7 @@ X11KeysymEnum::process_keymap(Display* dpy)
       const char* keysym_str = XKeysymToString(keysym);
       if (!keysym_str)
       {
-        log_error << "couldn't convert keysym " << keysym << " to string";
+        log_warn("couldn't convert keysym " << keysym << " to string");
       }
       else
       {
diff --git a/src/linux_uinput.cpp b/src/linux_uinput.cpp
index dac8453..67ddd28 100644
--- a/src/linux_uinput.cpp
+++ b/src/linux_uinput.cpp
@@ -44,7 +44,7 @@ LinuxUinput::LinuxUinput(DeviceType device_type, const std::string& name_, uint1
   ff_callback(),
   needs_sync(true)
 {
-  log_debug << name << " " << vendor << ":" << product << std::endl;
+  log_debug(name << " " << vendor << ":" << product);
 
   std::fill_n(abs_lst, ABS_CNT, false);
   std::fill_n(rel_lst, REL_CNT, false);
@@ -97,7 +97,7 @@ LinuxUinput::~LinuxUinput()
 void
 LinuxUinput::add_abs(uint16_t code, int min, int max, int fuzz, int flat)
 {
-  log_debug << "add_abs: " << abs2str(code) << " (" << min << ", " << max << ") " << name << std::endl;
+  log_debug("add_abs: " << abs2str(code) << " (" << min << ", " << max << ") " << name);
 
   if (!abs_lst[code])
   {
@@ -121,7 +121,7 @@ LinuxUinput::add_abs(uint16_t code, int min, int max, int fuzz, int flat)
 void
 LinuxUinput::add_rel(uint16_t code)
 {
-  log_debug << "add_rel: " << rel2str(code) << " " << name << std::endl;
+  log_debug("add_rel: " << rel2str(code) << " " << name);
 
   if (!rel_lst[code])
   {
@@ -140,7 +140,7 @@ LinuxUinput::add_rel(uint16_t code)
 void
 LinuxUinput::add_key(uint16_t code)
 {
-  log_debug << "add_key: " << key2str(code) << " " << name << std::endl;
+  log_debug("add_key: " << key2str(code) << " " << name);
 
   if (!key_lst[code])
   {
@@ -226,7 +226,7 @@ LinuxUinput::finish()
   user_dev.id.vendor  = vendor;
   user_dev.id.product = product;
 
-  log_debug << "'" << user_dev.name << "' " << user_dev.id.vendor << ":" << user_dev.id.product << std::endl;
+  log_debug("'" << user_dev.name << "' " << user_dev.id.vendor << ":" << user_dev.id.product);
 
   if (ff_bit)
     user_dev.ff_effects_max = ff_handler->get_max_effects();
@@ -241,14 +241,14 @@ LinuxUinput::finish()
     }
     else
     {
-      log_debug << "write return value: " << write_ret << std::endl; 
+      log_debug("write return value: " << write_ret);
     }
   }
 
   // FIXME: check that the config isn't empty and give a more
   // meaningful message when it is
 
-  log_debug << "finish" << std::endl;
+  log_debug("finish");
   if (ioctl(fd, UI_DEV_CREATE))
   {
     raise_exception(std::runtime_error, "unable to create uinput device: '" << name << "': " << strerror(errno));
@@ -296,10 +296,7 @@ LinuxUinput::update(int msec_delta)
 
     ff_handler->update(msec_delta);
 
-    if (0)
-      std::cout << boost::format("%5d %5d") 
-        % ff_handler->get_weak_magnitude() 
-        % ff_handler->get_strong_magnitude() << std::endl;
+    log_info(boost::format("%5d %5d") % ff_handler->get_strong_magnitude() % ff_handler->get_weak_magnitude());
 
     if (ff_callback)
     {
@@ -314,7 +311,9 @@ LinuxUinput::update(int msec_delta)
     if (ret < 0)
     {
       if (errno != EAGAIN)
-        std::cout << "Error: " << strerror(errno) << " " << ret << std::endl;
+      {
+        log_error("failed to read from file description: " << ret << ": " << strerror(errno));
+      }
     }
     else if (ret == sizeof(ev))
     { // successful read
@@ -326,7 +325,7 @@ LinuxUinput::update(int msec_delta)
           if (ev.code == LED_MISC)
           {
             // FIXME: implement this
-            std::cout << "unimplemented: Set LED status: " << ev.value << std::endl;
+            log_info("unimplemented: set LED status: " << ev.value);
           }
           break;
 
@@ -385,19 +384,19 @@ LinuxUinput::update(int msec_delta)
             break;
 
             default: 
-              std::cout << "Unhandled event code read" << std::endl;
+              log_warn("unhandled event code read");
               break;
           }
           break;
 
         default:
-          std::cout << "Unhandled event type read: " << ev.type << std::endl;
+          log_warn("unhandled event type read: " << ev.type);
           break;
       }
     }
     else
     {
-      std::cout << "uInput::update: short read: " << ret << std::endl;
+      log_warn("short read: " << ret);
     }
   }
 }
diff --git a/src/log.cpp b/src/log.cpp
index 7979965..cf036fe 100644
--- a/src/log.cpp
+++ b/src/log.cpp
@@ -18,6 +18,10 @@
 
 #include "log.hpp"
 
+#include <iostream>
+
+Logger g_logger;
+
 std::string log_pretty_print(const std::string& str)
 {
   // FIXME: very basic, might not work with complex return types
@@ -37,4 +41,43 @@ std::string log_pretty_print(const std::string& str)
   return str.substr(function_start);
 }
 
+Logger::Logger() :
+  m_log_level(kWarning)
+{}
+
+void
+Logger::set_level(LogLevel level)
+{
+  m_log_level = level;
+}
+
+Logger::LogLevel
+Logger::get_log_level() const
+{
+  return m_log_level;
+}
+
+void
+Logger::append_unchecked(LogLevel level, const std::string& str)
+{
+  switch(level)
+  {
+    case kError:   std::cout << "[ERROR] "; break;
+    case kWarning: std::cout << "[WARN] "; break;
+    case kInfo:    std::cout << "[INFO] "; break;
+    case kDebug:   std::cout << "[DEBUG] "; break;
+  }
+    
+  std::cout << str << std::endl;
+}
+
+void
+Logger::append(LogLevel level, const std::string& str) 
+{
+  if (m_log_level >= level)
+  {
+    append_unchecked(level, str);
+  }
+}
+
 /* EOF */
diff --git a/src/log.hpp b/src/log.hpp
index 4705d7d..99679ad 100644
--- a/src/log.hpp
+++ b/src/log.hpp
@@ -19,26 +19,80 @@
 #ifndef HEADER_XBOXDRV_LOG_HPP
 #define HEADER_XBOXDRV_LOG_HPP
 
-#include <iostream>
 #include <string>
 
 /** Takes __PRETTY_FUNCTION__ and tries to shorten it to the form:
     Classname::function() */
 std::string log_pretty_print(const std::string& str);
 
-/** informal status messages that don't indicate a fault in the
-    program */
-#define log_info  (std::cout << log_pretty_print(__PRETTY_FUNCTION__) << ": ")
+class Logger
+{
+public:
+  enum LogLevel {
+    /** things that shouldn't happen (i.e. a catched exceptions) */
+    kError,
 
-/** messages that indicate an recoverable error (i.e. a catched
-    exceptions) */
-#define log_warning (std::cout << log_pretty_print(__PRETTY_FUNCTION__) << ": ")
+    /** messages that indicate an recoverable error (i.e. a catched
+        exceptions) */
+    kWarning,
 
-/** things that shouldn't happen (i.e. a catched exceptions) */
-#define log_error (std::cout << log_pretty_print(__PRETTY_FUNCTION__) << ": ")
+    /** informal status messages that don't indicate a fault in the
+        program */
+    kInfo,
 
-/** extra verbose debugging messages */
-#define log_debug if (true); else (std::cout << log_pretty_print(__PRETTY_FUNCTION__) << ": ")
+    /** extra verbose debugging messages */
+    kDebug
+  };
+
+private:
+  LogLevel m_log_level;
+
+public:
+  Logger();
+  void set_level(LogLevel level);
+  LogLevel get_log_level() const;
+  void append(LogLevel level, const std::string& str);
+  void append_unchecked(LogLevel level, const std::string& str);
+
+};
+
+#define log_debug(text) do { \
+  if (g_logger.get_log_level() >= Logger::kDebug) \
+  { \
+    std::ostringstream x6ac1c382;             \
+    x6ac1c382 << log_pretty_print(__PRETTY_FUNCTION__) << ": " << text; \
+    g_logger.append_unchecked(Logger::kDebug, x6ac1c382.str()); \
+  } \
+} while(false)
+
+#define log_info(text) do { \
+  if (g_logger.get_log_level() >= Logger::kInfo) \
+  { \
+    std::ostringstream x6ac1c382;             \
+    x6ac1c382 << log_pretty_print(__PRETTY_FUNCTION__) << ": " << text; \
+    g_logger.append_unchecked(Logger::kInfo, x6ac1c382.str()); \
+  } \
+} while(false)
+
+#define log_warn(text) do { \
+  if (g_logger.get_log_level() >= Logger::kWarning) \
+  { \
+    std::ostringstream x6ac1c382;             \
+    x6ac1c382 << log_pretty_print(__PRETTY_FUNCTION__) << ": " << text; \
+    g_logger.append_unchecked(Logger::kWarning, x6ac1c382.str()); \
+  } \
+} while(false)
+
+#define log_error(text) do { \
+  if (g_logger.get_log_level() >= Logger::kError) \
+  { \
+    std::ostringstream x6ac1c382;             \
+    x6ac1c382 << log_pretty_print(__PRETTY_FUNCTION__) << ": " << text; \
+    g_logger.append_unchecked(Logger::kError, x6ac1c382.str()); \
+  } \
+} while(false)
+
+extern Logger g_logger;
 
 #endif
 
diff --git a/src/uinput.cpp b/src/uinput.cpp
index 37c78f3..aa3146d 100644
--- a/src/uinput.cpp
+++ b/src/uinput.cpp
@@ -42,7 +42,7 @@ UInput::create_uinput_device(uint32_t device_id)
   }
   else
   {
-    log_debug << "create device: " << device_id << std::endl;
+    log_debug("create device: " << device_id);
     LinuxUinput::DeviceType device_type = LinuxUinput::kGenericDevice;
     std::ostringstream dev_name;
     dev_name << "Xbox Gamepad (userspace driver)";
@@ -71,7 +71,7 @@ UInput::create_uinput_device(uint32_t device_id)
     boost::shared_ptr<LinuxUinput> dev(new LinuxUinput(device_type, dev_name.str(), 0x0000, 0x0000));
     uinput_devs.insert(std::pair<int, boost::shared_ptr<LinuxUinput> >(device_id, dev));
 
-    log_debug << "created uinput device: " << device_id << " - '" << dev_name.str() << "'" << std::endl;
+    log_debug("created uinput device: " << device_id << " - '" << dev_name.str() << "'");
 
     return dev.get();
   }
diff --git a/src/uinput_message_processor.cpp b/src/uinput_message_processor.cpp
index b92c929..ed95511 100644
--- a/src/uinput_message_processor.cpp
+++ b/src/uinput_message_processor.cpp
@@ -61,7 +61,7 @@ UInputMessageProcessor::send(const XboxGenericMsg& msg_in, int msec_delta)
         // switch to the next input mapping
         m_config->next_config();
 
-        log_info << "Next Config" << std::endl;
+        log_info("switched to config: " << m_config->get_current_config());
       }
     }
 
diff --git a/src/usb_read_thread.cpp b/src/usb_read_thread.cpp
index 6356bb0..70b2dbb 100644
--- a/src/usb_read_thread.cpp
+++ b/src/usb_read_thread.cpp
@@ -113,7 +113,7 @@ USBReadThread::run()
     }
     else
     {
-      log_error << "error while reading from USB: " << usb_strerror(ret) << std::endl;
+      log_error("error while reading from USB: " << usb_strerror(ret));
       m_stop = true;
     }
   }
diff --git a/src/xbox360_controller.cpp b/src/xbox360_controller.cpp
index 0691176..f184d92 100644
--- a/src/xbox360_controller.cpp
+++ b/src/xbox360_controller.cpp
@@ -42,8 +42,8 @@ Xbox360Controller::Xbox360Controller(libusb_device* dev_,
 {
   find_endpoints();
   
-  log_debug << "EP(IN):  " << endpoint_in << std::endl;
-  log_debug << "EP(OUT): " << endpoint_out << std::endl;
+  log_debug("EP(IN):  " << endpoint_in);
+  log_debug("EP(OUT): " << endpoint_out);
   
   int ret = libusb_open(dev, &handle);
 
@@ -114,8 +114,6 @@ Xbox360Controller::find_endpoints()
     raise_exception(std::runtime_error, "libusb_get_config_descriptor() failed: " << usb_strerror(ret));
   }
 
-  bool debug_print = false;
-
   // FIXME: no need to search all interfaces, could just check the one we acutally use
   for(const libusb_interface* interface = config->interface;
       interface != config->interface + config->bNumInterfaces;
@@ -125,16 +123,14 @@ Xbox360Controller::find_endpoints()
         altsetting != interface->altsetting + interface->num_altsetting;
         ++altsetting)
     {
-      if (debug_print) std::cout << "  Interface: " << static_cast<int>(altsetting->bInterfaceNumber) << std::endl;
+      log_debug("Interface: " << static_cast<int>(altsetting->bInterfaceNumber));
           
       for(const libusb_endpoint_descriptor* endpoint = altsetting->endpoint; 
           endpoint != altsetting->endpoint + altsetting->bNumEndpoints; 
           ++endpoint)
       {
-        if (debug_print) 
-          std::cout << "    Endpoint: " << int(endpoint->bEndpointAddress & LIBUSB_ENDPOINT_ADDRESS_MASK)
-                    << "(" << ((endpoint->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) ? "IN" : "OUT") << ")"
-                    << std::endl;
+        log_debug("    Endpoint: " << int(endpoint->bEndpointAddress & LIBUSB_ENDPOINT_ADDRESS_MASK) <<
+                  "(" << ((endpoint->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) ? "IN" : "OUT") << ")");
 
         if (altsetting->bInterfaceClass    == LIBUSB_CLASS_VENDOR_SPEC &&
             altsetting->bInterfaceSubClass == 93 &&
@@ -206,19 +202,13 @@ Xbox360Controller::read(XboxGenericMsg& msg, bool verbose, int timeout)
   }
   else if (len == 0)
   {
-    if (verbose)
-    {
-      std::cout << "zero length read" << std::endl;
-      // happens with the Xbox360 controller every now and then, just
-      // ignore, seems harmless, so just ignore
-    }
+    // happens with the Xbox360 controller every now and then, just
+    // ignore, seems harmless, so just ignore
+    log_debug("zero length read");
   }
   else if (len == 3 && data[0] == 0x01 && data[1] == 0x03)
   { 
-    if (verbose)
-    {
-      std::cout << "Xbox360Controller: LED Status: " << int(data[2]) << std::endl;
-    }
+    log_info("Xbox360Controller: LED Status: " << int(data[2]));
   }
   else if (len == 3 && data[0] == 0x03 && data[1] == 0x03)
   { 
@@ -228,7 +218,7 @@ Xbox360Controller::read(XboxGenericMsg& msg, bool verbose, int timeout)
       // data[2] == 0x01 unknown, but rumble works
       // data[2] == 0x02 unknown, but rumble works
       // data[2] == 0x03 is default with rumble enabled
-      std::cout << "Xbox360Controller: Rumble Status: " << int(data[2]) << std::endl;
+      log_info("Xbox360Controller: rumble status: " << int(data[2]));
     }
   }
   else if (len == 3 && data[0] == 0x08 && data[1] == 0x03)
@@ -237,23 +227,23 @@ Xbox360Controller::read(XboxGenericMsg& msg, bool verbose, int timeout)
     // port, so that we don't have to send chatpad init
     if (data[2] == 0x00)
     {
-      log_info << "peripheral: none" << std::endl;
+      log_info("peripheral: none");
     }
     else if (data[2] == 0x01)
     {
-      log_info << "peripheral: chatpad" << std::endl;
+      log_info("peripheral: chatpad");
     }
     else if (data[2] == 0x02)
     {
-      log_info << "peripheral: headset" << std::endl;
+      log_info("peripheral: headset");
     }
     else if (data[2] == 0x03)
     {
-      log_info << "peripheral: headset, chatpad" << std::endl;
+      log_info("peripheral: headset, chatpad");
     }
     else
     {
-      log_info << "peripheral: unknown: " << int(data[2]) << std::endl;
+      log_info("peripheral: unknown: " << int(data[2]));
     }
   }
   else if (len == 20 && data[0] == 0x00 && data[1] == 0x14)
@@ -264,7 +254,7 @@ Xbox360Controller::read(XboxGenericMsg& msg, bool verbose, int timeout)
   }
   else
   {
-    log_debug << "unknown: " << raw2str(data, len) << std::endl;
+    log_debug("unknown: " << raw2str(data, len));
   }
 
   return false;
diff --git a/src/xbox360_wireless_controller.cpp b/src/xbox360_wireless_controller.cpp
index c49dc8b..45ff273 100644
--- a/src/xbox360_wireless_controller.cpp
+++ b/src/xbox360_wireless_controller.cpp
@@ -120,25 +120,25 @@ Xbox360WirelessController::read(XboxGenericMsg& msg, bool verbose, int timeout)
   { // Connection Status Message
     if (data[1] == 0x00) 
     {
-      log_info << "Connection status: nothing" << std::endl;
+      log_info("connection status: nothing");
     } 
     else if (data[1] == 0x80) 
     {
-      log_info << "Connection status: controller connected" << std::endl;
+      log_info("connection status: controller connected");
       set_led(led_status);
     } 
     else if (data[1] == 0x40) 
     {
-      log_info << "Connection status: headset connected" << std::endl;
+      log_info("Connection status: headset connected");
     }
     else if (data[1] == 0xc0) 
     {
-      log_info << "Connection status: controller and headset connected" << std::endl;
+      log_info("Connection status: controller and headset connected");
       set_led(led_status);
     }
     else
     {
-      log_info << "Connection status: unknown" << std::endl;
+      log_info("Connection status: unknown");
     }
   }
   else if (len == 29)
@@ -154,8 +154,8 @@ Xbox360WirelessController::read(XboxGenericMsg& msg, bool verbose, int timeout)
                 % int(data[12])
                 % int(data[13])).str();
       battery_status = data[17];
-      log_info << "Serial: " << serial << std::endl;
-      log_info << "Battery Status: " << battery_status << std::endl;
+      log_info("Serial: " << serial);
+      log_info("Battery Status: " << battery_status);
     }
     else if (data[0] == 0x00 && data[1] == 0x01 && data[2] == 0x00 && data[3] == 0xf0 && data[4] == 0x00 && data[5] == 0x13)
     { // Event message
@@ -166,7 +166,7 @@ Xbox360WirelessController::read(XboxGenericMsg& msg, bool verbose, int timeout)
     else if (data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x00 && data[3] == 0x13)
     { // Battery status
       battery_status = data[4];
-      log_info << "Battery Status: " << battery_status << std::endl;
+      log_info("battery status: " << battery_status);
     }
     else if (data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x00 && data[3] == 0xf0)
     {
@@ -175,7 +175,7 @@ Xbox360WirelessController::read(XboxGenericMsg& msg, bool verbose, int timeout)
     }
     else
     {
-      log_debug << "unknown: " << raw2str(data, len) << std::endl;
+      log_debug("unknown: " << raw2str(data, len));
     }
   }
   else if (len == 0)
@@ -184,7 +184,7 @@ Xbox360WirelessController::read(XboxGenericMsg& msg, bool verbose, int timeout)
   }
   else
   {
-    log_debug << "unknown: " << raw2str(data, len) << std::endl;
+    log_debug("unknown: " << raw2str(data, len));
   }
 
   return false;
diff --git a/src/xbox_controller.cpp b/src/xbox_controller.cpp
index 13d9ced..8d876f2 100644
--- a/src/xbox_controller.cpp
+++ b/src/xbox_controller.cpp
@@ -68,8 +68,6 @@ XboxController::find_endpoints()
     raise_exception(std::runtime_error, "libusb_get_config_descriptor() failed: " << usb_strerror(ret));
   }
 
-  bool debug_print = false;
-
   // FIXME: no need to search all interfaces, could just check the one we acutally use
   for(const libusb_interface* interface = config->interface;
       interface != config->interface + config->bNumInterfaces;
@@ -79,17 +77,15 @@ XboxController::find_endpoints()
         altsetting != interface->altsetting + interface->num_altsetting;
         ++altsetting)
     {
-      if (debug_print) std::cout << "  Interface: " << static_cast<int>(altsetting->bInterfaceNumber) << std::endl;
+      log_debug("  Interface: " << static_cast<int>(altsetting->bInterfaceNumber));
           
       for(const libusb_endpoint_descriptor* endpoint = altsetting->endpoint; 
           endpoint != altsetting->endpoint + altsetting->bNumEndpoints; 
           ++endpoint)
       {
-        if (debug_print)
-          std::cout << "    Endpoint: " << int(endpoint->bEndpointAddress & LIBUSB_ENDPOINT_ADDRESS_MASK)
-                    << "(" << ((endpoint->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) ? "IN" : "OUT") << ")"
-                    << std::endl;
-
+        log_debug("    Endpoint: " << int(endpoint->bEndpointAddress & LIBUSB_ENDPOINT_ADDRESS_MASK) <<
+                  "(" << ((endpoint->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) ? "IN" : "OUT") << ")");
+                  
         if (altsetting->bInterfaceClass    == 88 &&
             altsetting->bInterfaceSubClass == 66 &&
             altsetting->bInterfaceProtocol == 0)
diff --git a/src/xboxdrv_daemon.cpp b/src/xboxdrv_daemon.cpp
index d8c10c5..66d3219 100644
--- a/src/xboxdrv_daemon.cpp
+++ b/src/xboxdrv_daemon.cpp
@@ -21,6 +21,7 @@
 #include <boost/format.hpp>
 #include <fstream>
 #include <stdexcept>
+#include <iostream>
 
 #include "uinput_message_processor.hpp"
 #include "dummy_message_processor.hpp"
@@ -130,9 +131,8 @@ XboxdrvDaemon::cleanup_threads()
 
   if (count > 0)
   {
-    log_info << "cleaned up " << count << " thread(s), free slots: " 
-             << get_free_slot_count() << "/" << m_controller_slots.size()
-             << std::endl;
+    log_info("cleaned up " << count << " thread(s), free slots: " <<
+             get_free_slot_count() << "/" << m_controller_slots.size());
   }
 }
 
@@ -149,15 +149,15 @@ XboxdrvDaemon::process_match(const Options& opts, struct udev_device* device)
 
   if (!get_usb_id(device, &vendor, &product))
   {
-    log_warning << "couldn't get vendor:product" << std::endl;
+    log_warn("couldn't get vendor:product");
   }
   else
   {
     XPadDevice dev_type;
     if (!find_xpad_device(vendor, product, &dev_type))
     {
-      log_info << "ignoring " << boost::format("%04x:%04x") % vendor % product
-               << " not a valid Xboxdrv device" << std::endl;
+      log_info("ignoring " << boost::format("%04x:%04x") % vendor % product <<
+               " not a valid Xboxdrv device");
     }
     else
     {  
@@ -165,14 +165,14 @@ XboxdrvDaemon::process_match(const Options& opts, struct udev_device* device)
       int dev;
       if (!get_usb_path(device, &bus, &dev))
       {
-        log_warning << "couldn't get bus:dev" << std::endl;
+        log_warn("couldn't get bus:dev");
       }
       else
       {
         ControllerSlot* slot = find_free_slot(vendor, product, bus, dev);
         if (!slot)
         {
-          log_error << "no free controller slot found, controller will be ignored" << std::endl;
+          log_error("no free controller slot found, controller will be ignored");
         }
         else
         {
@@ -182,7 +182,7 @@ XboxdrvDaemon::process_match(const Options& opts, struct udev_device* device)
           }
           catch(const std::exception& err)
           {
-            log_error << "failed to launch XboxdrvThread: " << err.what() << std::endl;
+            log_error("failed to launch XboxdrvThread: " << err.what());
           }
         }
       }
@@ -196,14 +196,14 @@ XboxdrvDaemon::init_uinput(const Options& opts)
   // Setup uinput
   if (opts.no_uinput)
   {
-    log_info << "starting without UInput" << std::endl;
+    log_info("starting without UInput");
 
     // just create some empty controller slots
     m_controller_slots.resize(opts.controller_slots.size());
   }
   else
   {
-    log_info << "starting with UInput" << std::endl;
+    log_info("starting with UInput");
 
     m_uinput.reset(new UInput());
 
@@ -213,7 +213,7 @@ XboxdrvDaemon::init_uinput(const Options& opts)
     for(Options::ControllerSlots::const_iterator controller = opts.controller_slots.begin(); 
         controller != opts.controller_slots.end(); ++controller)
     {
-      log_info << "creating slot: " << slot_count << std::endl;
+      log_info("creating slot: " << slot_count);
       m_controller_slots.push_back(ControllerSlot(m_controller_slots.size(),
                                                   ControllerSlotConfig::create(*m_uinput, slot_count,
                                                                                opts.extra_devices,
@@ -222,7 +222,7 @@ XboxdrvDaemon::init_uinput(const Options& opts)
       slot_count += 1;
     }
 
-    log_info << "created " << m_controller_slots.size() << " controller slots" << std::endl;
+    log_info("created " << m_controller_slots.size() << " controller slots");
 
     // After all the ControllerConfig registered their events, finish up
     // the device creation
@@ -291,7 +291,7 @@ XboxdrvDaemon::create_pid_file(const Options& opts)
 {
   if (!opts.pid_file.empty())
   {
-    log_info << "writing pid file: " << opts.pid_file << std::endl;
+    log_info("writing pid file: " << opts.pid_file);
     std::ofstream out(opts.pid_file.c_str());
     if (!out)
     {
@@ -319,7 +319,7 @@ XboxdrvDaemon::run(const Options& opts)
   }
   catch(const std::exception& err)
   {
-    log_error << "fatal exception: " << err.what() << std::endl;
+    log_error("fatal exception: " << err.what());
   }
 }
 
@@ -473,7 +473,7 @@ XboxdrvDaemon::launch_xboxdrv(const XPadDevice& dev_type, const Options& opts,
 
   if (!dev)
   {
-    log_error << "USB device disappeared before it could be opened" << std::endl;
+    log_error("USB device disappeared before it could be opened");
   }
   else
   {
@@ -495,12 +495,11 @@ XboxdrvDaemon::launch_xboxdrv(const XPadDevice& dev_type, const Options& opts,
     thread->start_thread(opts);
     slot.thread = thread.release();
 
-    log_info << "launched XboxdrvThread for " << boost::format("%03d:%03d")
+    log_info("launched XboxdrvThread for " << boost::format("%03d:%03d")
       % static_cast<int>(busnum) 
       % static_cast<int>(devnum)
              << " in slot " << slot.id << ", free slots: " 
-             << get_free_slot_count() << "/" << m_controller_slots.size()
-             << std::endl;
+             << get_free_slot_count() << "/" << m_controller_slots.size());
   }
 }
 
diff --git a/src/xboxdrv_thread.cpp b/src/xboxdrv_thread.cpp
index 90b0457..93613b8 100644
--- a/src/xboxdrv_thread.cpp
+++ b/src/xboxdrv_thread.cpp
@@ -18,6 +18,7 @@
 
 #include "xboxdrv_thread.hpp"
 
+#include <iostream>
 #include <sys/wait.h>
 
 #include "helper.hpp"
@@ -52,9 +53,9 @@ XboxdrvThread::~XboxdrvThread()
 {
   if (m_thread.get())
   {
-    log_info << "waiting for thread to join: " << m_thread->get_id() << std::endl;
+    log_info("waiting for thread to join: " << m_thread->get_id());
     stop_thread(); 
-    log_info << "thread joined" << std::endl;
+    log_info("thread joined");
   }
 }
 
@@ -75,7 +76,7 @@ XboxdrvThread::launch_child_process()
 
       if (execvp(m_child_exec[0].c_str(), argv) == -1)
       {
-        std::cout << "error: " << m_child_exec[0] << ": " << strerror(errno) << std::endl;
+        log_error("error: " << m_child_exec[0] << ": " << strerror(errno));
         // FIXME: must signal the parent process
         _exit(EXIT_FAILURE);
       }
@@ -98,17 +99,17 @@ XboxdrvThread::watch_chid_process()
       {
         if (WEXITSTATUS(status) != 0)
         {
-          std::cout << "error: child program has stopped with exit status " << WEXITSTATUS(status) << std::endl;
+          log_error("child program has stopped with exit status " << WEXITSTATUS(status));
         }
         else
         {
-          std::cout << "child program exited successful" << std::endl;
+          log_info("child program exited successful");
         }
         global_exit_xboxdrv = true;
       }
       else if (WIFSIGNALED(status))
       {
-        std::cout << "error: child program was terminated by " << WTERMSIG(status) << std::endl;
+        log_error("child program was terminated by " << WTERMSIG(status));
         global_exit_xboxdrv = true;
       }
     }
@@ -162,7 +163,7 @@ XboxdrvThread::controller_loop(const Options& opts)
   catch(const std::exception& err)
   {
     // catch read errors from USB and other stuff that can go wrong
-    log_error << err.what() << std::endl;
+    log_error(err.what());
   }
 
   {