Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: refactory cpp metric #914

Closed
wants to merge 14 commits into from
3 changes: 2 additions & 1 deletion core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/dependencies.cmake)
# Subdirectories (modules).
set(SUB_DIRECTORIES_LIST
aggregator app_config checkpoint common config config_manager config_server_pb
controller event event_handler event_listener helper log_pb logger monitor
controller event event_handler event_listener helper log_pb logger monitor ilogtail_metric
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

加一个指标开发文档

parser plugin polling processor profiler reader profile_sender sender shennong sdk
fuse sls_control
)
Expand Down Expand Up @@ -119,6 +119,7 @@ target_link_libraries(${LOGTAIL_TARGET}
controller
plugin
monitor
iLogtail_metric
sender
profiler
profile_sender
Expand Down
3 changes: 3 additions & 0 deletions core/config/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,9 @@ LogFileReader* Config::CreateLogFileReader(const std::string& dir,
}

if (reader != NULL) {

reader->SetFileMetric(ILogtailMetric::GetInstance()->createFileMetric(mConfigName, "FileInput", dir + file));

if ("customized" == mTopicFormat) {
reader->SetTopicName(STRING_DEEP_COPY(mCustomizedTopic));
}
Expand Down
2 changes: 2 additions & 0 deletions core/config/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include "processor/BaseFilterNode.h"
#include "LogType.h"
#include "IntegrityConfig.h"
#include "ILogtailMetric.h"
#include "MetricConstants.h"

namespace logtail {

Expand Down
1 change: 1 addition & 0 deletions core/config_manager/ConfigManagerBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,7 @@ void ConfigManagerBase::LoadSingleUserConfig(const std::string& logName, const J

UserLogConfigParser::ParseAdvancedConfig(value, *config);
}

if (logType == DELIMITER_LOG) {
config->mTimeFormat = GetStringValue(value, "timeformat", "");
string separatorStr = GetStringValue(value, "delimiter_separator");
Expand Down
2 changes: 2 additions & 0 deletions core/config_manager/ConfigManagerBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include "common/Lock.h"
#include "common/Thread.h"
#include "event/Event.h"
#include "ILogtailMetric.h"
#include "MetricConstants.h"

DECLARE_FLAG_BOOL(https_verify_peer);
DECLARE_FLAG_STRING(https_ca_cert);
Expand Down
2 changes: 2 additions & 0 deletions core/controller/EventDispatcherBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#include "shennong/MetricSender.h"
#include "polling/PollingDirFile.h"
#include "polling/PollingModify.h"
#include "ilogtail_metric/MetricExportor.h"
#ifdef APSARA_UNIT_TEST_MAIN
#include "polling/PollingEventQueue.h"
#endif
Expand Down Expand Up @@ -868,6 +869,7 @@ bool EventDispatcherBase::Dispatch() {
DumpCheckPointPeriod(curTime);
if (curTime - lastCheckDir >= INT32_FLAG(main_loop_check_interval)) {
LogFileProfiler::GetInstance()->SendProfileData();
MetricExportor::GetInstance()->pushMetrics();
#if defined(__linux__)
CheckShennong();
#endif
Expand Down
30 changes: 30 additions & 0 deletions core/ilogtail_metric/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2022 iLogtail Authors
#
# 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.

cmake_minimum_required(VERSION 2.9)
project(iLogtail_metric)

if (MSVC)
add_definitions(-DTARGETLIBS=Psapi.lib)
add_definitions(-DPSAPI_VERSION=1)
endif ()

file(GLOB LIB_SOURCE_FILES *.cpp *.h)
append_source_files(LIB_SOURCE_FILES)
add_library(${PROJECT_NAME} STATIC ${LIB_SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} log_pb)

if (MSVC)
target_link_libraries(${PROJECT_NAME} "Psapi.lib")
endif ()
119 changes: 119 additions & 0 deletions core/ilogtail_metric/ILogtaiMetric.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#include "ILogtailMetric.h"

namespace logtail {


ILogtailMetric::ILogtailMetric() {
}

ILogtailMetric::~ILogtailMetric() {
}

BaseMetric::BaseMetric() {
mMetricObj = new MetricObj;
mMetricObj->val = {0};
mMetricObj->timestamp = time(NULL);
}

BaseMetric::BaseMetric(MetricObj* metricObj) {
mMetricObj = metricObj;
}

BaseMetric::~BaseMetric() {
if (mMetricObj) {
delete mMetricObj;
}
}


void BaseMetric::baseMetricAdd(uint64_t val) {
mMetricObj->val += val;
mMetricObj->timestamp = {time(NULL)};
}

BaseMetric::MetricObj* BaseMetric::snapShotMetricObj() {
MetricObj* newMetricObj = new MetricObj;

LOG_INFO(sLogger, ("mMetricObj->val exchange before", mMetricObj->val));
long value = mMetricObj->val.exchange(0);
newMetricObj->val = {value};
LOG_INFO(sLogger, ("mMetricObj->val exchange after", mMetricObj->val));

LOG_INFO(sLogger, ("mMetricObj->timestamp exchange after", mMetricObj->timestamp));
newMetricObj->timestamp = {time(NULL)};
LOG_INFO(sLogger, ("mMetricObj->timestamp exchange after", mMetricObj->timestamp));

return newMetricObj;
}

BaseMetric::MetricObj* BaseMetric::getMetricObj() {
return mMetricObj;
}


BaseMetricPtr PipelineMetric::getBaseMetric(std::string metricField) {
LOG_INFO(sLogger, ("getBaseMetric", metricField));
std::unordered_map<std::string, BaseMetricPtr>::iterator iter = mBaseMetrics.find(metricField);
if (iter != mBaseMetrics.end()) {
return iter->second;
} else {
BaseMetricPtr base(new BaseMetric());
mBaseMetrics.insert(std::pair<std::string, BaseMetricPtr>(metricField, base));
return base;
}
}


PipelineMetricPtr ILogtailMetric::createPipelineMetric(std::list<std::string> fields , std::unordered_map<std::string, std::string> labels) {
PipelineMetricPtr fileMetric(new PipelineMetric());

LOG_INFO(sLogger, ("label size before", fileMetric->mLabels.size()));

fileMetric->mLabels = labels;

LOG_INFO(sLogger, ("label size before", fileMetric->mLabels.size()));

for (std::list<std::string>::iterator it = fields.begin(); it != fields.end(); ++it) {
BaseMetricPtr base(new BaseMetric());
fileMetric->mBaseMetrics.insert(std::pair<std::string, BaseMetricPtr>(*it, base));
}
std::lock_guard<std::mutex> lock(mMetricsLock);
mPipelineMetrics.push_back(fileMetric);
return fileMetric;
}

void ILogtailMetric::deletePipelineMetric(PipelineMetricPtr pipelineMetric) {
std::lock_guard<std::mutex> lock(mMetricsLock);
mPipelineMetrics.remove(pipelineMetric);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这是O(n)的,我感觉要O(1)删的话,可能得自己实现双向链表并持有其Node,而非val

}


PipelineMetricPtr ILogtailMetric::createFileMetric(std::string configUid, std::string pluginUid, std::string filePath) {
std::unordered_map<std::string, std::string> labels;
LOG_INFO(sLogger, ("label size before", labels.size()));

labels.insert(std::pair<std::string, std::string>("configUid", configUid));
labels.insert(std::pair<std::string, std::string>("pluginUid", pluginUid));
labels.insert(std::pair<std::string, std::string>("filePath", filePath));

LOG_INFO(sLogger, ("label size before", labels.size()));
std::list<std::string> fields;
fields.push_back(METRIC_FILE_READ_COUNT);
fields.push_back(METRIC_FILE_READ_BYTES);
return createPipelineMetric(fields, labels);
}


BaseMetricPtr ILogtailMetric::getBaseMetric(PipelineMetricPtr pipelineMetric, std::string metricField) {
LOG_INFO(sLogger, ("getBaseMetric", metricField));
std::unordered_map<std::string, BaseMetricPtr>::iterator iter = pipelineMetric->mBaseMetrics.find(metricField);
if (iter != pipelineMetric->mBaseMetrics.end()) {
return iter->second;
} else {
BaseMetricPtr base(new BaseMetric());
pipelineMetric->mBaseMetrics.insert(std::pair<std::string, BaseMetricPtr>(metricField, base));
return base;
}
}

}
71 changes: 71 additions & 0 deletions core/ilogtail_metric/ILogtailMetric.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#pragma once
#include <string>
#include <unordered_map>
#include <list>
#include <atomic>
#include "logger/Logger.h"
#include <MetricConstants.h>


namespace logtail {


class BaseMetric{
struct MetricObj {
/* counters and gauges */
std::atomic_long val;

std::atomic_long timestamp;
};
public:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

代码风格好像不符合clangformat

BaseMetric();
BaseMetric(MetricObj* metricObj);
~BaseMetric();
MetricObj* mMetricObj;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有没有必要分2层?是想如何扩展这个结构呢?

void baseMetricAdd(uint64_t val);
MetricObj* getMetricObj();
MetricObj* snapShotMetricObj();
};

typedef std::shared_ptr<BaseMetric> BaseMetricPtr;


class PipelineMetric {
public:
std::unordered_map<std::string, BaseMetricPtr> mBaseMetrics;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个也不太确定是否有必要用map

std::unordered_map<std::string, std::string> mLabels;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有没有必要使用map?这个数据是不是第一次创建后就不变的?也没有查的需求


BaseMetricPtr getBaseMetric(std::string metricField);

};

typedef std::shared_ptr<PipelineMetric> PipelineMetricPtr;

class ILogtailMetric {

private:
ILogtailMetric();
~ILogtailMetric();


public:
static ILogtailMetric* GetInstance() {
static ILogtailMetric* ptr = new ILogtailMetric();
return ptr;
}

std::mutex mMetricsLock;

std::list<PipelineMetricPtr> mPipelineMetrics;
PipelineMetricPtr mInstanceMetric;

PipelineMetricPtr createPipelineMetric(std::list<std::string> fields , std::unordered_map<std::string, std::string> labels);

PipelineMetricPtr createFileMetric(std::string configUid, std::string pluginUid, std::string filePath);

BaseMetricPtr getBaseMetric(PipelineMetricPtr pipelineMetric, std::string metricField);

void deletePipelineMetric(PipelineMetricPtr pipelineMetric);

};
}
25 changes: 25 additions & 0 deletions core/ilogtail_metric/MetricConstants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2022 iLogtail Authors
*
* 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 <string>

namespace logtail {

const std::string METRIC_FILE_READ_COUNT = "file_read_count";
const std::string METRIC_FILE_READ_BYTES = "file_read_bytes";

} // namespace logtail
Loading
Loading