Skip to content

Commit

Permalink
[MDAPI-211][C++] Implement logging management. (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
AnatolyKalin authored Dec 11, 2024
2 parents c161bf0 + f09bd21 commit 1abff20
Show file tree
Hide file tree
Showing 9 changed files with 317 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ set(dxFeedGraalCxxApi_Isolated_Sources
src/isolated/ipf/IsolatedInstrumentProfileReader.cpp
src/isolated/ipf/live/IsolatedInstrumentProfileCollector.cpp
src/isolated/ipf/live/IsolatedInstrumentProfileConnection.cpp
src/isolated/logging/IsolatedLogging.cpp
src/isolated/model/IsolatedTxModelListener.cpp
src/isolated/model/IsolatedIndexedTxModel.cpp
src/isolated/model/IsolatedTimeSeriesTxModel.cpp
Expand Down Expand Up @@ -267,6 +268,10 @@ set(dxFeedGraalCxxApi_Ipf_Sources
src/ipf/live/IterableInstrumentProfile.cpp
)

set(dxFeedGraalCxxApi_Logging_Sources
src/logging/Logging.cpp
)

set(dxFeedGraalCxxApi_Model_Sources
src/model/TxModelListener.cpp
src/model/IndexedTxModel.cpp
Expand Down Expand Up @@ -376,6 +381,7 @@ set(dxFeedGraalCxxApi_Sources
${dxFeedGraalCxxApi_ApiOsub_Sources}
${dxFeedGraalCxxApi_Auth_Sources}
${dxFeedGraalCxxApi_Ipf_Sources}
${dxFeedGraalCxxApi_Logging_Sources}
${dxFeedGraalCxxApi_Model_Sources}
${dxFeedGraalCxxApi_OnDemand_Sources}
${dxFeedGraalCxxApi_Promise_Sources}
Expand Down
2 changes: 2 additions & 0 deletions ReleaseNotes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
* **\[MDAPI-211]\[C++]** Implement logging management
* Added `Logging` class.
* **\[MDAPI-82]\[C++]** Implement MarketDepthModel
* Added `MarketDepthModel` class.
* Added `MarketDepthModelListener` class.
Expand Down
3 changes: 3 additions & 0 deletions include/dxfeed_graal_cpp_api/api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251 4996)
#include "isolated/ipf/live/IsolatedInstrumentProfileCollector.hpp"
#include "isolated/ipf/live/IsolatedInstrumentProfileConnection.hpp"
#include "isolated/ipf/IsolatedInstrumentProfileReader.hpp"
#include "isolated/logging/IsolatedLogging.hpp"
#include "isolated/model/IsolatedTxModelListener.hpp"
#include "isolated/model/IsolatedIndexedTxModel.hpp"
#include "isolated/model/IsolatedTimeSeriesTxModel.hpp"
Expand All @@ -84,6 +85,8 @@ DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251 4996)
#include "isolated/schedule/IsolatedSession.hpp"
#include "isolated/schedule/IsolatedSchedule.hpp"

#include "logging/Logging.hpp"

#include "ondemand/OnDemandService.hpp"

#include "promise/Promise.hpp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include "../../internal/Common.hpp"

#include <dxfeed_graal_cpp_api/event/EventTypeEnum.hpp>

DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251)

DXFCPP_BEGIN_NAMESPACE
Expand Down
38 changes: 38 additions & 0 deletions include/dxfeed_graal_cpp_api/isolated/logging/IsolatedLogging.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2024 Devexperts LLC.
// SPDX-License-Identifier: MPL-2.0

#pragma once

#include "../../internal/Conf.hpp"

#include "../../logging/Logging.hpp"
#include "dxfeed_graal_cpp_api/internal/JavaObjectHandle.hpp"

#include <cstdint>
#include <string>
#include <vector>

DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251)

DXFCPP_BEGIN_NAMESPACE

namespace isolated::logging::IsolatedLogging {

// int32_t dxfg_logging_listener_new(graal_isolatethread_t *thread, dxfg_logging_listener_function_t user_func,
// void *user_data, DXFG_OUT dxfg_logging_listener_t **listener);
JavaObjectHandle<Logging::ListenerTag> createListener(void* userFunc, void* userData);

// int32_t dxfg_logging_set_listener(graal_isolatethread_t *thread, dxfg_logging_listener_t *listener);
void setListener(const JavaObjectHandle<Logging::ListenerTag>& listener);

//int32_t dxfg_logging_set_log_level(graal_isolatethread_t *thread, dxfg_logging_level_t level);
void setLogLevel(Logging::Level level);

//int32_t dxfg_logging_set_err_level(graal_isolatethread_t *thread, dxfg_logging_level_t level);
void setErrFileLevel(Logging::Level level);

}

DXFCPP_END_NAMESPACE

DXFCXX_DISABLE_MSC_WARNINGS_POP()
112 changes: 112 additions & 0 deletions include/dxfeed_graal_cpp_api/logging/Logging.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright (c) 2024 Devexperts LLC.
// SPDX-License-Identifier: MPL-2.0

#pragma once

#include "../internal/Conf.hpp"
#include "dxfeed_graal_cpp_api/internal/Handler.hpp"

DXFCXX_DISABLE_MSC_WARNINGS_PUSH(4251)

#include "../internal/Common.hpp"

DXFCPP_BEGIN_NAMESPACE

/**
*
*/
struct DXFCPP_EXPORT Logging final {
struct ListenerTag {};
/**
* Defines a set of standard logging levels that can be used to control logging output.
*/
enum class Level {
/// Indicates that all messages should be logged.
ALL = 0,

/// Indicates a highly detailed tracing message.
TRACE,

/// Is a message level providing tracing debug information.
DEBUG,

/// Is a message level for informational messages.
INFO,

/// Is a message level indicating a potential problem.
WARN,

/// Is a message level indicating a serious failure.
ERROR,

/// Is a special level that can be used to turn off logging.
OFF,
};

static std::string levelToString(Level level);

private:
static SimpleHandler<void(Level, std::int64_t /*timestamp*/, const std::string & /*threadName*/,
std::int64_t /*threadId*/, const std::string & /*loggerName*/,
const std::string & /*message*/)>
handler_;

struct Impl;

public:
/**
* Initializes logging and sets the logging level.
*
* This is equivalent to the following code:
*
* ```cpp
* System::setProperty("log.className", "com.devexperts.logging.InterceptableLogging");
* System::setProperty("log.level", levelToString(level));
* System::setProperty("err.level", levelToString(level));
* ```
* @param level The logging level.
*/
static void init(Level level = Level::OFF);

/**
* Initializes logging, sets the path to the logging file and the logging level.
*
* This is equivalent to the following code:
*
* ```cpp
* System::setProperty("log.className", "com.devexperts.logging.InterceptableLogging");
* System::setProperty("log.file", logFile);
* System::setProperty("log.level", levelToString(logLevel));
* ```
*
* @param logFile The logging file.
* @param logLevel The logging level.
*/
static void init(const std::string &logFile, Level logLevel = Level::INFO);

/**
* Initializes logging, sets the path to the file for logging, to the file for outputting errors and warnings, and
* sets the logging level for both files.
*
* This is equivalent to the following code:
*
* ```cpp
* System::setProperty("log.className", "com.devexperts.logging.InterceptableLogging");
* System::setProperty("log.file", logFile);
* System::setProperty("log.level", levelToString(logLevel));
* System::setProperty("err.file", errFile);
* System::setProperty("err.level", levelToString(errFileLevel));
* ```
*
* @param logFile The logging file.
* @param errFile The err file.
* @param logLevel The logging level.
* @param errFileLevel The err file logging level.
*/
static void init(const std::string &logFile, const std::string &errFile, Level logLevel = Level::INFO,
Level errFileLevel = Level::WARN);
};

DXFCPP_END_NAMESPACE

DXFCXX_DISABLE_MSC_WARNINGS_POP()
2 changes: 2 additions & 0 deletions src/internal/JavaObjectHandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,6 @@ template struct JavaObjectHandle<TimeSeriesTxModel::Builder>;

template struct JavaObjectHandle<ExecutorTag>;

template struct JavaObjectHandle<Logging::ListenerTag>;

DXFCPP_END_NAMESPACE
54 changes: 54 additions & 0 deletions src/isolated/logging/IsolatedLogging.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) 2024 Devexperts LLC.
// SPDX-License-Identifier: MPL-2.0

#include <dxfg_api.h>

#include <dxfeed_graal_cpp_api/isolated/IsolatedCommon.hpp>
#include <dxfeed_graal_cpp_api/isolated/internal/IsolatedString.hpp>
#include <dxfeed_graal_cpp_api/isolated/logging/IsolatedLogging.hpp>

DXFCPP_BEGIN_NAMESPACE

namespace isolated::logging::IsolatedLogging {

// int32_t dxfg_logging_listener_new(graal_isolatethread_t *thread, dxfg_logging_listener_function_t user_func,
// void *user_data, DXFG_OUT dxfg_logging_listener_t **listener);
JavaObjectHandle<Logging::ListenerTag> createListener(void *userFunc, void *userData) {
if (!userFunc) {
throw InvalidArgumentException("Unable to execute function `dxfg_logging_listener_new`. The "
"`userFunc` is nullptr");
}

dxfg_logging_listener_t *isolatedListener{};

runGraalFunctionAndThrowIfMinusOne(dxfg_logging_listener_new,
dxfcpp::bit_cast<dxfg_logging_listener_function_t>(userFunc), userData,
&isolatedListener);

return JavaObjectHandle<Logging::ListenerTag>(isolatedListener);
}

// int32_t dxfg_logging_set_listener(graal_isolatethread_t *thread, dxfg_logging_listener_t *listener);
void setListener(const JavaObjectHandle<Logging::ListenerTag> &listener) {
if (!listener) {
throw InvalidArgumentException("Unable to execute function `dxfg_logging_set_listener`. The "
"`listener` handle is invalid");
}

runGraalFunctionAndThrowIfMinusOne(dxfg_logging_set_listener,
dxfcpp::bit_cast<dxfg_logging_listener_t *>(listener.get()));
}

// int32_t dxfg_logging_set_log_level(graal_isolatethread_t *thread, dxfg_logging_level_t level);
void setLogLevel(Logging::Level level) {
runGraalFunctionAndThrowIfMinusOne(dxfg_logging_set_log_level, static_cast<dxfg_logging_level_t>(level));
}

// int32_t dxfg_logging_set_err_level(graal_isolatethread_t *thread, dxfg_logging_level_t level);
void setErrFileLevel(Logging::Level level) {
runGraalFunctionAndThrowIfMinusOne(dxfg_logging_set_err_level, static_cast<dxfg_logging_level_t>(level));
}

} // namespace isolated::logging::IsolatedLogging

DXFCPP_END_NAMESPACE
98 changes: 98 additions & 0 deletions src/logging/Logging.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright (c) 2024 Devexperts LLC.
// SPDX-License-Identifier: MPL-2.0

#include <dxfeed_graal_cpp_api/logging/Logging.hpp>
#include <dxfeed_graal_cpp_api/system/System.hpp>

#include <dxfg_api.h>

#include <dxfeed_graal_cpp_api/isolated/event/IsolatedEventType.hpp>
#include <dxfeed_graal_cpp_api/isolated/internal/IsolatedObject.hpp>
#include <dxfeed_graal_cpp_api/isolated/logging/IsolatedLogging.hpp>
#include <utility>

DXFCPP_BEGIN_NAMESPACE

std::string Logging::levelToString(Level level) {
switch (level) {
case Level::ALL:
return "ALL";
case Level::TRACE:
return "TRACE";
case Level::DEBUG:
return "DEBUG";
case Level::INFO:
return "INFO";
case Level::WARN:
return "WARN";
case Level::ERROR:
return "ERROR";
case Level::OFF:
return "OFF";
}

return "UNKNOWN";
}

SimpleHandler<void(Logging::Level, std::int64_t /*timestamp*/, const std::string & /*threadName*/,
std::int64_t /*threadId*/, const std::string & /*loggerName*/, const std::string & /*message*/)>
Logging::handler_{};

struct Logging::Impl {
static JavaObjectHandle<Logging::ListenerTag> listenerHandle;

static void onLog(graal_isolatethread_t * /*thread*/, dxfg_logging_level_t level, int64_t timestamp,
const char *threadName, int64_t threadId, const char *loggerName, const char *message,
dxfg_exception_t * /*exception*/, const char * /*formattedMessage*/, void * /*userData*/) {
handler_(static_cast<Level>(level), timestamp, threadName, threadId, loggerName, message);
}
};

JavaObjectHandle<Logging::ListenerTag> Logging::Impl::listenerHandle{};

void Logging::init(Level level) {
System::setProperty("log.className", "com.devexperts.logging.InterceptableLogging");
System::setProperty("log.level", levelToString(level));
System::setProperty("err.level", levelToString(level));
}

void Logging::init(const std::string &logFile, Level logLevel) {
System::setProperty("log.className", "com.devexperts.logging.InterceptableLogging");
System::setProperty("log.file", logFile);
System::setProperty("log.level", levelToString(logLevel));
}

void Logging::init(const std::string &logFile, const std::string &errFile, Level logLevel, Level errFileLevel) {
System::setProperty("log.className", "com.devexperts.logging.InterceptableLogging");
System::setProperty("log.file", logFile);
System::setProperty("log.level", levelToString(logLevel));
System::setProperty("err.file", errFile);
System::setProperty("err.level", levelToString(errFileLevel));
}

// void Logging::setListener(std::function<void(Level, std::int64_t, const std::string &, std::int64_t,
// const std::string &, const std::string &)>
// listener) {
// static auto id = static_cast<std::size_t>(-1);
//
// if (id != static_cast<std::size_t>(-1)) {
// handler_ -= id;
// }
//
// id = handler_ += std::move(listener);
//
// if (!Impl::listenerHandle) {
// Impl::listenerHandle =
// isolated::logging::IsolatedLogging::createListener(dxfcpp::bit_cast<void *>(&Impl::onLog), nullptr);
// }
// }
//
// void Logging::setLogLevel(Level level) {
// isolated::logging::IsolatedLogging::setLogLevel(level);
// }
//
// void Logging::setErrFileLevel(Level level) {
// isolated::logging::IsolatedLogging::setErrFileLevel(level);
// }

DXFCPP_END_NAMESPACE

0 comments on commit 1abff20

Please sign in to comment.