Skip to content

Commit

Permalink
ZmqLogger: Add optional dumping to stderr
Browse files Browse the repository at this point in the history
Add an openshot::Settings boolean `DEBUG_TO_STDERR`, which when
set true will direct all AppendDebugMethod() messages to std::clog,
in addition to (possibly) being sent over the ZeroMQ wire.
  • Loading branch information
ferdnyc committed Feb 1, 2020
1 parent 49972b2 commit fc18366
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 46 deletions.
3 changes: 3 additions & 0 deletions include/Settings.h
Expand Up @@ -124,6 +124,9 @@ namespace openshot {
/// The audio device name to use during playback
std::string PLAYBACK_AUDIO_DEVICE_NAME = "";

/// Whether to dump ZeroMQ debug messages to stderr
bool DEBUG_TO_STDERR = false;

/// Create or get an instance of this logger singleton (invoke the class with this method)
static Settings * Instance();
};
Expand Down
23 changes: 13 additions & 10 deletions include/ZmqLogger.h
Expand Up @@ -43,6 +43,7 @@
#include <zmq.hpp>
#include <unistd.h>
#include "JuceHeader.h"
#include "Settings.h"


namespace openshot {
Expand Down Expand Up @@ -70,17 +71,17 @@ namespace openshot {
zmq::socket_t *publisher;

/// Default constructor
ZmqLogger(){}; // Don't allow user to create an instance of this singleton
ZmqLogger(){}; // Don't allow user to create an instance of this singleton

#if __GNUC__ >=7
/// Default copy method
ZmqLogger(ZmqLogger const&) = delete; // Don't allow the user to assign this instance
ZmqLogger(ZmqLogger const&) = delete; // Don't allow the user to assign this instance

/// Default assignment operator
ZmqLogger & operator=(ZmqLogger const&) = delete; // Don't allow the user to assign this instance
#else
/// Default copy method
ZmqLogger(ZmqLogger const&) {}; // Don't allow the user to assign this instance
ZmqLogger(ZmqLogger const&) {}; // Don't allow the user to assign this instance

/// Default assignment operator
ZmqLogger & operator=(ZmqLogger const&); // Don't allow the user to assign this instance
Expand All @@ -94,13 +95,15 @@ namespace openshot {
static ZmqLogger * Instance();

/// Append debug information
void AppendDebugMethod(std::string method_name,
std::string arg1_name="", float arg1_value=-1.0,
std::string arg2_name="", float arg2_value=-1.0,
std::string arg3_name="", float arg3_value=-1.0,
std::string arg4_name="", float arg4_value=-1.0,
std::string arg5_name="", float arg5_value=-1.0,
std::string arg6_name="", float arg6_value=-1.0);
void AppendDebugMethod(
std::string method_name,
std::string arg1_name="", float arg1_value=-1.0,
std::string arg2_name="", float arg2_value=-1.0,
std::string arg3_name="", float arg3_value=-1.0,
std::string arg4_name="", float arg4_value=-1.0,
std::string arg5_name="", float arg5_value=-1.0,
std::string arg6_name="", float arg6_value=-1.0
);

/// Close logger (sockets and/or files)
void Close();
Expand Down
7 changes: 4 additions & 3 deletions src/Settings.cpp
Expand Up @@ -34,14 +34,14 @@ using namespace std;
using namespace openshot;


// Global reference to logger
// Global reference to Settings
Settings *Settings::m_pInstance = NULL;

// Create or Get an instance of the logger singleton
// Create or Get an instance of the settings singleton
Settings *Settings::Instance()
{
if (!m_pInstance) {
// Create the actual instance of logger only once
// Create the actual instance of Settings only once
m_pInstance = new Settings;
m_pInstance->HARDWARE_DECODER = 0;
m_pInstance->HIGH_QUALITY_SCALING = false;
Expand All @@ -55,6 +55,7 @@ Settings *Settings::Instance()
m_pInstance->HW_DE_DEVICE_SET = 0;
m_pInstance->HW_EN_DEVICE_SET = 0;
m_pInstance->PLAYBACK_AUDIO_DEVICE_NAME = "";
m_pInstance->DEBUG_TO_STDERR = false;
}

return m_pInstance;
Expand Down
73 changes: 40 additions & 33 deletions src/ZmqLogger.cpp
Expand Up @@ -29,12 +29,13 @@
*/

#include "../include/ZmqLogger.h"
#include <thread>
#include <chrono>

#if USE_RESVG == 1
#include "ResvgQt.h"
#endif

using namespace std;
using namespace openshot;


Expand Down Expand Up @@ -64,17 +65,16 @@ ZmqLogger *ZmqLogger::Instance()
// This can only happen 1 time or it will crash
ResvgRenderer::initLog();
#endif

}

return m_pInstance;
}

// Set the connection for this logger
void ZmqLogger::Connection(string new_connection)
void ZmqLogger::Connection(std::string new_connection)
{
// Create a scoped lock, allowing only a single thread to run the following code at one time
const GenericScopedLock<CriticalSection> lock(loggerCriticalSection);
const juce::GenericScopedLock<juce::CriticalSection> lock(loggerCriticalSection);

// Does anything need to happen?
if (new_connection == connection)
Expand Down Expand Up @@ -102,27 +102,27 @@ void ZmqLogger::Connection(string new_connection)
publisher->bind(connection.c_str());

} catch (zmq::error_t &e) {
cout << "ZmqLogger::Connection - Error binding to " << connection << ". Switching to an available port." << endl;
std::cout << "ZmqLogger::Connection - Error binding to " << connection << ". Switching to an available port." << std::endl;
connection = "tcp://*:*";
publisher->bind(connection.c_str());
}

// Sleeping to allow connection to wake up (0.25 seconds)
usleep(250000);
std::this_thread::sleep_for(std::chrono::milliseconds(250));
}

void ZmqLogger::Log(string message)
void ZmqLogger::Log(std::string message)
{
if (!enabled)
// Don't do anything
return;

// Create a scoped lock, allowing only a single thread to run the following code at one time
const GenericScopedLock<CriticalSection> lock(loggerCriticalSection);
const juce::GenericScopedLock<juce::CriticalSection> lock(loggerCriticalSection);

// Send message over socket (ZeroMQ)
zmq::message_t reply (message.length());
memcpy (reply.data(), message.c_str(), message.length());
std::memcpy (reply.data(), message.c_str(), message.length());
publisher->send(reply);

// Write to log file (if opened, and force it to write to disk in case of a crash)
Expand All @@ -131,14 +131,14 @@ void ZmqLogger::Log(string message)
}

// Log message to a file (if path set)
void ZmqLogger::LogToFile(string message)
void ZmqLogger::LogToFile(std::string message)
{
// Write to log file (if opened, and force it to write to disk in case of a crash)
if (log_file.is_open())
log_file << message << std::flush;
}

void ZmqLogger::Path(string new_path)
void ZmqLogger::Path(std::string new_path)
{
// Update path
file_path = new_path;
Expand All @@ -148,14 +148,14 @@ void ZmqLogger::Path(string new_path)
log_file.close();

// Open file (write + append)
log_file.open (file_path.c_str(), ios::out | ios::app);
log_file.open (file_path.c_str(), std::ios::out | std::ios::app);

// Get current time and log first message
time_t now = time(0);
tm* localtm = localtime(&now);
log_file << "------------------------------------------" << endl;
log_file << "libopenshot logging: " << asctime(localtm);
log_file << "------------------------------------------" << endl;
std::time_t now = std::time(0);
std::tm* localtm = std::localtime(&now);
log_file << "------------------------------------------" << std::endl;
log_file << "libopenshot logging: " << std::asctime(localtm);
log_file << "------------------------------------------" << std::endl;
}

void ZmqLogger::Close()
Expand All @@ -176,27 +176,28 @@ void ZmqLogger::Close()
}

// Append debug information
void ZmqLogger::AppendDebugMethod(string method_name,
string arg1_name, float arg1_value,
string arg2_name, float arg2_value,
string arg3_name, float arg3_value,
string arg4_name, float arg4_value,
string arg5_name, float arg5_value,
string arg6_name, float arg6_value)
void ZmqLogger::AppendDebugMethod(std::string method_name,
std::string arg1_name, float arg1_value,
std::string arg2_name, float arg2_value,
std::string arg3_name, float arg3_value,
std::string arg4_name, float arg4_value,
std::string arg5_name, float arg5_value,
std::string arg6_name, float arg6_value)
{
if (!enabled)
if (!enabled && !openshot::Settings::Instance()->DEBUG_TO_STDERR)
// Don't do anything
return;

{
// Create a scoped lock, allowing only a single thread to run the following code at one time
const GenericScopedLock<CriticalSection> lock(loggerCriticalSection);
const juce::GenericScopedLock<juce::CriticalSection> lock(loggerCriticalSection);

stringstream message;
message << fixed << setprecision(4);
std::stringstream message;
message << std::fixed << std::setprecision(4);

// Construct message
message << method_name << " (";

// Add attributes to method JSON
if (arg1_name.length() > 0)
message << arg1_name << "=" << arg1_value;

Expand All @@ -215,10 +216,16 @@ void ZmqLogger::AppendDebugMethod(string method_name,
if (arg6_name.length() > 0)
message << ", " << arg6_name << "=" << arg6_value;

// Output to standard output
message << ")" << endl;
message << ")" << std::endl;

if (openshot::Settings::Instance()->DEBUG_TO_STDERR) {
// Print message to stderr
std::clog << message.str();
}

// Send message through ZMQ
Log(message.str());
if (enabled) {
// Send message through ZMQ
Log(message.str());
}
}
}

0 comments on commit fc18366

Please sign in to comment.