Skip to content

Commit

Permalink
Merge pull request #243 from project-tsurugi/wip/i_1003
Browse files Browse the repository at this point in the history
Wip/i 1003
  • Loading branch information
t-horikawa authored Oct 31, 2024
2 parents 19552b1 + 9754eab commit 24b4aa9
Show file tree
Hide file tree
Showing 16 changed files with 925 additions and 47 deletions.
3 changes: 3 additions & 0 deletions include/tateyama/framework/component_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,8 @@ constexpr inline component::id_type service_id_remote_kvs = 5;
constexpr inline component::id_type service_id_debug = 6;
constexpr inline component::id_type service_id_session = 7;
constexpr inline component::id_type service_id_metrics = 8;
#ifdef ENABLE_ALTIMETER
constexpr inline component::id_type service_id_altimeter = 9;
#endif

}
7 changes: 7 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ file(GLOB SOURCES
"tateyama/metrics/resource/*.cpp"
)

if (ENABLE_ALTIMETER)
file(GLOB ALTIMETER_SOURCES
"tateyama/altimeter/service/*.cpp"
)
list(APPEND SOURCES ${ALTIMETER_SOURCES})
endif()

if(TRACY_ENABLE)
file(GLOB TRACY_CLIENT
"../third_party/tracy/public/TracyClient.cpp"
Expand Down
51 changes: 51 additions & 0 deletions src/tateyama/altimeter/service/bridge.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2018-2024 Project Tsurugi.
*
* 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 "bridge.h"

namespace tateyama::altimeter::service {

using tateyama::api::server::request;
using tateyama::api::server::response;

using namespace framework;

component::id_type bridge::id() const noexcept {
return tag;
}

bool bridge::setup(environment&) {
core_ = std::make_unique<core>();
return true;
}

bool bridge::start(environment&) {
return true;
}

bool bridge::shutdown(environment&) {
return true;
}

bool bridge::operator()(std::shared_ptr<request> req, std::shared_ptr<response> res) {
return core_->operator()(req, res);
}

std::string_view bridge::label() const noexcept {
return component_label;
}

}
100 changes: 100 additions & 0 deletions src/tateyama/altimeter/service/bridge.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright 2018-2024 Project Tsurugi.
*
* 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.
*/
#pragma once

#include <functional>
#include <memory>
#include <type_traits>

#include <tateyama/framework/service.h>
#include <tateyama/framework/repository.h>
#include <tateyama/api/server/request.h>
#include <tateyama/api/server/response.h>
#include <tateyama/framework/environment.h>
#include <tateyama/framework/component_ids.h>
#include <tateyama/altimeter/service/core.h>

namespace tateyama::altimeter::service {

using tateyama::api::server::request;
using tateyama::api::server::response;

/**
* @brief altimeter resource bridge for tateyama framework
* @details This object bridges altimeter as a resource component in tateyama framework.
* This object should be responsible only for life-cycle management.
*/
class bridge : public framework::service {
public:
static constexpr id_type tag = framework::service_id_altimeter;

[[nodiscard]] id_type id() const noexcept override;

//@brief human readable label of this component
static constexpr std::string_view component_label = "altimeter_service";

/**
* @brief setup the component (the state will be `ready`)
*/
bool setup(framework::environment&) override;

/**
* @brief start the component (the state will be `activated`)
*/
bool start(framework::environment&) override;

/**
* @brief shutdown the component (the state will be `deactivated`)
*/
bool shutdown(framework::environment&) override;

bool operator()(
std::shared_ptr<request> req,
std::shared_ptr<response> res) override;

/**
* @brief create empty object
*/
bridge() = default;

bridge(bridge const& other) = delete;
bridge& operator=(bridge const& other) = delete;
bridge(bridge&& other) noexcept = delete;
bridge& operator=(bridge&& other) noexcept = delete;

/**
* @brief destructor the object
*/
~bridge() = default;

/**
* @see `tateyama::framework::component::label()`
*/
[[nodiscard]] std::string_view label() const noexcept override;

/**
* @brief replace altimeter helper object, provided for test purpose
* @param helper the helper object to replace
*/
void replace_helper(std::shared_ptr<altimeter_helper> helper) {
core_->replace_helper(std::move(helper));
}

private:
std::shared_ptr<tateyama::altimeter::service::core> core_{};
};

}
149 changes: 149 additions & 0 deletions src/tateyama/altimeter/service/core.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
* Copyright 2018-2024 Project Tsurugi.
*
* 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 <altimeter/logger.h>
#include <altimeter/event/event_logger.h>

#include <tateyama/altimeter/service/core.h>

#include <tateyama/api/configuration.h>
#include <tateyama/framework/component_ids.h>
#include <tateyama/framework/service.h>

#include <tateyama/proto/altimeter/request.pb.h>
#include <tateyama/proto/altimeter/response.pb.h>
#include <tateyama/proto/diagnostics.pb.h>

namespace tateyama::altimeter::service {

using tateyama::api::server::request;
using tateyama::api::server::response;

class altimeter_helper_direct : public altimeter_helper {
public:
void enable(std::string_view) override {
// FIXME not implemented in altimeter
// ::altimeter::logger::enable(t);
}
void disable(std::string_view) override {
// FIXME not implemented in altimeter
// ::altimeter::logger::disable(t);
}
void set_level(std::string_view t, std::uint64_t v) override {
::altimeter::logger::set_level(t, v);
}
void set_stmt_duration_threshold(std::uint64_t v) override {
::altimeter::event::event_logger::set_stmt_duration_threshold(v);
}
void rotate_all(std::string_view t) override {
::altimeter::logger::rotate_all(t);
}
};

bool tateyama::altimeter::service::core::operator()(const std::shared_ptr<request>& req, const std::shared_ptr<response>& res) {
tateyama::proto::altimeter::request::Request rq{};

auto data = req->payload();
if(!rq.ParseFromArray(data.data(), static_cast<int>(data.size()))) {
LOG(INFO) << "request parse error";
return true; // It indicates a possible malfunction in the communication system, but let's continue the operation.
}

res->session_id(req->session_id());
switch(rq.command_case()) {
case tateyama::proto::altimeter::request::Request::kConfigure:
{
auto configure = rq.configure();
if (configure.has_event_log()) {
auto log_settings = configure.event_log();
if (log_settings.enabled_opt_case() == tateyama::proto::altimeter::request::LogSettings::EnabledOptCase::kEnabled) {
if (log_settings.enabled()) {
helper_->enable("event");
} else {
helper_->disable("event");
}
send_error<tateyama::proto::altimeter::response::Configure>(res, tateyama::proto::altimeter::response::ErrorKind::UNKNOWN, "event log [enable|disable] is not implemented"); // FIXME remove this and the following lines
return true; // Error notification is treated as normal termination.
}
if (log_settings.level_opt_case() == tateyama::proto::altimeter::request::LogSettings::LevelOptCase::kLevel) {
auto v = log_settings.level();
helper_->set_level("event", v);
}
if (log_settings.statement_duration_opt_case() == tateyama::proto::altimeter::request::LogSettings::StatementDurationOptCase::kStatementDuration) {
auto v = log_settings.statement_duration();
helper_->set_stmt_duration_threshold(v);
}
}
if (configure.has_audit_log()) {
auto log_settings = configure.audit_log();
if (log_settings.enabled_opt_case() == tateyama::proto::altimeter::request::LogSettings::EnabledOptCase::kEnabled) {
if (log_settings.enabled()) {
helper_->enable("audit");
} else {
helper_->disable("audit");
}
send_error<tateyama::proto::altimeter::response::Configure>(res, tateyama::proto::altimeter::response::ErrorKind::UNKNOWN, "audit log [enable|disable] is not implemented"); // FIXME remove this and the following lines
return true; // Error notification is treated as normal termination.
}
if (log_settings.level_opt_case() == tateyama::proto::altimeter::request::LogSettings::LevelOptCase::kLevel) {
auto v = log_settings.level();
helper_->set_level("audit", v);
}
}
tateyama::proto::altimeter::response::Configure rs{};
(void) rs.mutable_success();
res->body(rs.SerializeAsString());
rs.clear_success();
break;
}

case tateyama::proto::altimeter::request::Request::kLogRotate:
{
auto log_lotate = rq.log_rotate();
switch(log_lotate.category()) {
case tateyama::proto::altimeter::common::LogCategory::EVENT:
helper_->rotate_all("event");
break;
case tateyama::proto::altimeter::common::LogCategory::AUDIT:
helper_->rotate_all("audit");
break;
default:
send_error<tateyama::proto::altimeter::response::LogRotate>(res, tateyama::proto::altimeter::response::ErrorKind::UNKNOWN, "log type for LogRotate is invalid");
return true; // Error notification is treated as normal termination.
}
tateyama::proto::altimeter::response::LogRotate rs{};
(void) rs.mutable_success();
res->body(rs.SerializeAsString());
rs.clear_success();
break;
}

case tateyama::proto::altimeter::request::Request::COMMAND_NOT_SET:
{
tateyama::proto::diagnostics::Record record{};
record.set_code(tateyama::proto::diagnostics::Code::INVALID_REQUEST);
record.set_message("request for altimeter is invalid");
res->error(record);
break;
}

}
return true;
}

core::core() : helper_(std::dynamic_pointer_cast<altimeter_helper>(std::make_shared<altimeter_helper_direct>())) {
}

}
Loading

0 comments on commit 24b4aa9

Please sign in to comment.