How to monitor the diagnostic
/*
* Copyright 2022-present ifm electronic, gmbh
* SPDX-License-Identifier: Apache-2.0
*/
#include "diagnostic.hpp"
#include <ifm3d/device/o3r.h>
#include <iostream>
#include <thread>
using namespace std::chrono_literals;
using namespace ifm3d::literals;
void CustomCallback(int id_, std::string message_){
std::clog << "Custom callback: " << id_ << " " << message_ << std::endl;
}
int main() {
// Get the IP from the environment if defined
const char *IP = std::getenv("IFM3D_IP") ? std::getenv("IFM3D_IP") : ifm3d::DEFAULT_IP.c_str();
std::clog << "IP: " << IP << std::endl;
auto o3r = std::make_shared<ifm3d::O3R>(IP);
// To log to file, use diagnostic(o3r, true, "file_name").
// Log outputs will be redirected both to the file and
// to the console.
auto log_to_file = false;
O3RDiagnostic diagnostic(o3r, log_to_file);
////////////////////////////////////////////////
// Examples on how to retrieve the diagnostic
// active and/or dormant.
////////////////////////////////////////////////
// Using ifm3d::json::object()
std::clog << "All current diagnostics:\n"
<< diagnostic.GetDiagnosticFiltered(ifm3d::json::object()).dump(4)
<< std::endl;
std::clog << "Active diagnostics:\n"
<< diagnostic.GetDiagnosticFiltered(
ifm3d::json::parse(R"({"state": "active"})")).dump(4)
<< std::endl
<< std::endl
<< std::endl;
////////////////////////////////////////////////
// Start the asynchronous diagnostic monitoring
// and display errors for "d" seconds.
////////////////////////////////////////////////
diagnostic.StartAsyncDiag(CustomCallback);
// You can also call the function without a custom
// callback, in which case the default callback will
// be used:
// diagnostic.StartAsyncDiag();
std::this_thread::sleep_for(20s);
diagnostic.StopAsyncDiag();
return 0;
}
/*
* Copyright 2022-present ifm electronic, gmbh
* SPDX-License-Identifier: Apache-2.0
*/
#include <cstdlib>
#include <fstream>
#include <functional>
#include <ifm3d/device/o3r.h>
#include <ifm3d/fg.h>
#include <iostream>
using namespace ifm3d::literals;
class O3RDiagnostic {
public:
O3RDiagnostic(ifm3d::O3R::Ptr o3r, bool log_to_file = false,
const std::string &file_name_ = "")
: o3r_(o3r), log_to_file_(log_to_file),
fg_(std::make_shared<ifm3d::FrameGrabber>(o3r_, 50009)),
consoleBuffer_(std::clog.rdbuf()) {
if (log_to_file_) {
const std::string &log_file_name =
(file_name_.empty()) ? "O3R_diagnostic.txt" : file_name_;
if (log_to_file_) {
logFile_.open(log_file_name, std::ios::app); // Open the log file
// Check if the file opened successfully
if (!logFile_.is_open()) {
std::cerr << "Failed to open log file: " << log_file_name
<< std::endl;
return;
}
std::streambuf *fileBuffer = logFile_.rdbuf();
// Redirect std::clog to the log file
std::clog.rdbuf(fileBuffer);
}
}
std::clog.rdbuf(consoleBuffer_);
}
ifm3d::json GetDiagnosticFiltered(ifm3d::json filter_mask_) {
return o3r_->GetDiagnosticFiltered(filter_mask_);
}
void StartAsyncDiag() {
fg_->OnAsyncError([this](int id_, const std::string &message_) {
this->AsyncDiagCallback_(id_, message_);
});
fg_->Start({});
}
void StartAsyncDiag(std::function<void(int, const std::string&)> callback) {
fg_->OnAsyncError(callback);
fg_->Start({});
}
void StopAsyncDiag() { fg_->Stop(); }
~O3RDiagnostic() {
// Stop the frame grabber if it's still running
fg_->Stop();
// Restore the console output stream buffer
std::clog.rdbuf(consoleBuffer_);
// Close the log file if it's open
if (logFile_.is_open()) {
logFile_.close();
}
}
private:
ifm3d::O3R::Ptr o3r_;
ifm3d::FrameGrabber::Ptr fg_;
std::streambuf *consoleBuffer_;
bool log_to_file_;
std::ofstream logFile_;
ifm3d::json diagnostic_ =
ifm3d::json::parse(R"({"id": "None", "message": "None"})");
void AsyncDiagCallback_(int id_, std::string message_) {
diagnostic_["id"] = id_;
diagnostic_["message"] = message_;
std::clog << "\n//////////////////////////////////" << std::endl;
std::clog << "Id: " << diagnostic_["id"] << std::endl;
std::clog << "Message: " << diagnostic_["message"] << std::endl;
}
};