diff --git a/frameworks/native/include/hilog_common.h b/frameworks/native/include/hilog_common.h index 1567e863fc993d98f1134344d3802cc9110e08d9..e9371c8864dd305869db00360e4636521a067d91 100644 --- a/frameworks/native/include/hilog_common.h +++ b/frameworks/native/include/hilog_common.h @@ -30,6 +30,8 @@ #define MULARGS 5 #define MAX_LOG_LEN 1024 /* maximum length of a log, include '\0' */ #define MAX_TAG_LEN 32 /* log tag size, include '\0' */ +#define MAX_DOMAINS 5 +#define MAX_TAGS 10 #define RET_SUCCESS 0 #define RET_FAIL (-1) #define IS_ONE(number, n) ((number>>n)&0x01) diff --git a/frameworks/native/include/hilogtool_msg.h b/frameworks/native/include/hilogtool_msg.h index 1cfe5a523992e4d0851b10cd42eaea733d472694..86a1f26a6f5c64bfcffa2e8985f4628af169a47c 100644 --- a/frameworks/native/include/hilogtool_msg.h +++ b/frameworks/native/include/hilogtool_msg.h @@ -101,12 +101,19 @@ typedef struct { typedef struct { MessageHeader header; + uint8_t nDomain; + uint8_t nNoDomain; + uint8_t nTag; + uint8_t nNoTag; uint8_t levels; uint16_t types; - uint32_t domain; - uint32_t timeBegin; - uint32_t timeEnd; + uint32_t domains[MAX_DOMAINS]; + char tags[MAX_TAGS][MAX_TAG_LEN]; uint16_t logCount; + uint8_t noLevels; + uint16_t noTypes; + uint32_t noDomains[MAX_DOMAINS]; + char noTags[MAX_TAGS][MAX_TAG_LEN]; } LogQueryRequest; typedef struct { @@ -314,37 +321,4 @@ typedef struct { std::string pidStr; } SetPropertyParam; - -typedef struct { - uint16_t noBlockMode; - uint16_t types; - uint16_t levels; - uint16_t headLines; - uint16_t tailLines; - time_t beginTime; - time_t endTime; - std::string domain; - std::string tag; - std::string regexArgs; - std::string buffSizeArgs; - std::string logFileCtrlArgs; - std::string compressArgs; - std::string fileSizeArgs; - std::string fileNumArgs; - std::string filePathArgs; - std::string fileNameArgs; - std::string jobIdArgs; - std::string personalArgs; - std::string logClearArgs; - std::string logTypeArgs; - std::string domainArgs; - std::string statisticArgs; - std::string tagArgs; - std::string logLevelArgs; - std::string flowSwitchArgs; - std::string flowQuotaArgs; - std::string pidArgs; - std::string algorithmArgs; -} HilogArgs; - #endif /* HILOGTOOL_MSG_H */ diff --git a/services/hilogd/include/log_reader.h b/services/hilogd/include/log_reader.h index aed5feb5d07b833b4cad247f9cbd4f7d6f4bf9f1..85f36b1e177b1fa610e2cd2b6a695fbf5414c8d7 100644 --- a/services/hilogd/include/log_reader.h +++ b/services/hilogd/include/log_reader.h @@ -33,11 +33,18 @@ class HilogBuffer; #define TYPE_PERSISTER 2 using QueryCondition = struct QueryCondition { + uint8_t nDomain = 0; + uint8_t nNoDomain = 0; + uint8_t nTag = 0; + uint8_t nNoTag = 0; uint16_t levels = 0; uint16_t types = 0; - uint32_t domain = 0; - uint32_t timeBegin = 0; - uint32_t timeEnd = 0; + uint32_t domains[MAX_DOMAINS]; + std::string tags[MAX_TAGS]; + uint8_t noLevels = 0; + uint16_t noTypes = 0; + uint32_t noDomains[MAX_DOMAINS]; + std::string noTags[MAX_TAGS]; }; class LogReader : public std::enable_shared_from_this { diff --git a/services/hilogd/log_buffer.cpp b/services/hilogd/log_buffer.cpp index 70c694f156f8a3edf3a591b07a10a5555e9e9674..fadacdaba3eebb79371e4dc1b5830812d11c114b 100644 --- a/services/hilogd/log_buffer.cpp +++ b/services/hilogd/log_buffer.cpp @@ -35,6 +35,9 @@ using namespace std; const float DROP_RATIO = 0.05; static int g_maxBufferSize = 4194304; static int g_maxBufferSizeByType[LOG_TYPE_MAX] = {1048576, 1048576, 1048576, 1048576}; +const int DOMAIN_STRICT_MASK = 0xd000000; +const int DOMAIN_FUZZY_MASK = 0xdffff; +const int DOMAIN_MODULE_BITS = 8; HilogBuffer::HilogBuffer() { @@ -52,6 +55,7 @@ HilogBuffer::~HilogBuffer() {} size_t HilogBuffer::Insert(const HilogMsg& msg) { + printf("insert: %s\n", CONTENT_PTR((&msg))); size_t eleSize = CONTENT_LEN((&msg)); /* include '\0' */ if (unlikely(msg.tag_len > MAX_TAG_LEN || msg.tag_len == 0 || eleSize > MAX_LOG_LEN || eleSize <= 0)) { @@ -328,36 +332,56 @@ int32_t HilogBuffer::ClearStatisticInfoByDomain(uint32_t domain) bool HilogBuffer::conditionMatch(std::shared_ptr reader) { - // domain, timeBegin & timeEnd are zero when not indicated - // domain condition - - /* patterns: + /* domain patterns: * strict mode: 0xdxxxxxx (full) * fuzzy mode: 0xdxxxx (using last 2 digits of full domain as mask) */ - const int DOMAIN_STRICT_MASK = 0xd000000; - const int DOMAIN_FUZZY_MASK = 0xdffff; - const int DOMAIN_MODULE_BITS = 8; - if ((reader->queryCondition.domain != 0) && - ((reader->queryCondition.domain >= DOMAIN_STRICT_MASK && - reader->queryCondition.domain != reader->readPos->domain) || - (reader->queryCondition.domain <= DOMAIN_FUZZY_MASK && - reader->queryCondition.domain != (reader->readPos->domain >> DOMAIN_MODULE_BITS))) - ) { + + if (((static_cast((0b01 << (reader->readPos->type)) & (reader->queryCondition.types)) == 0) || + (static_cast((0b01 << (reader->readPos->level)) & (reader->queryCondition.types)) == 0))) return false; + + int ret = 0; + if (reader->queryCondition.nDomain > 0) { + for (int i = 0; i < reader->queryCondition.nDomain; i++) { + uint32_t domains = reader->queryCondition.domains[i]; + if (!((domains >= DOMAIN_STRICT_MASK && domains != reader->readPos->domain) || + (domains <= DOMAIN_FUZZY_MASK && domains != (reader->readPos->domain >> DOMAIN_MODULE_BITS)))) { + ret = 1; + break; + } + } + if (ret == 0) return false; + ret = 0; } - - // time condition - if ((reader->queryCondition.timeBegin == 0 && reader->queryCondition.timeEnd == 0) || - ((reader->readPos->tv_sec >= reader->queryCondition.timeBegin) && - (reader->readPos->tv_sec <= reader->queryCondition.timeEnd))) { - // type and level condition - if ((static_cast((0b01 << (reader->readPos->type)) & (reader->queryCondition.types)) != 0) && - (static_cast((0b01 << (reader->readPos->level)) & (reader->queryCondition.levels)) != 0)) { - return true; + if (reader->queryCondition.nTag > 0) { + for (int i = 0; i < reader->queryCondition.nTag; i++) { + if (reader->readPos->tag == reader->queryCondition.tags[i]) { + ret = 1; + break; } + } + if (ret == 0) return false; } - return false; + // domain exclusion + if (reader->queryCondition.nNoDomain != 0) { + for (int i = 0; i < reader->queryCondition.nNoDomain; i++) { + uint32_t noDomains = reader->queryCondition.noDomains[i]; + if (((noDomains >= DOMAIN_STRICT_MASK && noDomains == reader->readPos->domain) || + (noDomains <= DOMAIN_FUZZY_MASK && noDomains == (reader->readPos->domain >> DOMAIN_MODULE_BITS)))) + return false; + } + } + if (reader->queryCondition.nNoTag > 0) { + for (int i = 0; i < reader->queryCondition.nNoTag; i++) { + if (reader->readPos->tag == reader->queryCondition.noTags[i]) return false; + } + } + if ((static_cast((0b01 << (reader->readPos->type)) & (reader->queryCondition.noTypes)) != 0) || + (static_cast((0b01 << (reader->readPos->level)) & (reader->queryCondition.noLevels)) != 0)) { + return false; + } + return true; } void HilogBuffer::ReturnNoLog(std::shared_ptr reader) diff --git a/services/hilogd/log_querier.cpp b/services/hilogd/log_querier.cpp index f88f7eae331f10dbfb0998bf96b141ff6bf22eff..e7126c3ac9b3642e34fb337ffc621bc2682d0625 100644 --- a/services/hilogd/log_querier.cpp +++ b/services/hilogd/log_querier.cpp @@ -101,17 +101,17 @@ LogPersisterRotator* MakeRotator(LogPersistStartMsg& pLogPersistStartMsg) }; } -void HandleLogQueryRequest(std::shared_ptr logReader, HilogBuffer* buffer) +void HandleLogQueryRequest(std::shared_ptr logReader, HilogBuffer& buffer) { logReader->SetCmd(LOG_QUERY_RESPONSE); - buffer->AddLogReader(logReader); - buffer->Query(logReader); + buffer.AddLogReader(logReader); + buffer.Query(logReader); } -void HandleNextRequest(std::shared_ptr logReader, HilogBuffer* buffer) +void HandleNextRequest(std::shared_ptr logReader, HilogBuffer& buffer) { logReader->SetCmd(NEXT_RESPONSE); - buffer->Query(logReader); + buffer.Query(logReader); } void HandlePersistStartRequest(char* reqMsg, std::shared_ptr logReader, HilogBuffer* buffer) @@ -407,6 +407,30 @@ void HandleBufferClearRequest(char* reqMsg, std::shared_ptr logReader logReader->hilogtoolConnectSocket->Write(msgToSend, sendMsgLen + sizeof(MessageHeader)); } +void SetCondition(std::shared_ptr logReader, const LogQueryRequest& qRstMsg) +{ + logReader->queryCondition.levels = qRstMsg.levels; + logReader->queryCondition.types = qRstMsg.types; + logReader->queryCondition.nDomain = qRstMsg.nDomain; + logReader->queryCondition.nTag = qRstMsg.nTag; + logReader->queryCondition.noLevels = qRstMsg.noLevels; + logReader->queryCondition.noTypes = qRstMsg.noTypes; + logReader->queryCondition.nNoDomain = qRstMsg.nNoDomain; + logReader->queryCondition.nNoTag = qRstMsg.nNoTag; + for (int i = 0; i < qRstMsg.nDomain; i++) { + logReader->queryCondition.domains[i] = qRstMsg.domains[i]; + } + for (int i = 0; i < qRstMsg.nTag; i++) { + logReader->queryCondition.tags[i] = qRstMsg.tags[i]; + } + for (int i = 0; i < qRstMsg.nNoDomain; i++) { + logReader->queryCondition.noDomains[i] = qRstMsg.noDomains[i]; + } + for (int i = 0; i < qRstMsg.nNoTag; i++) { + logReader->queryCondition.noTags[i] = qRstMsg.noTags[i]; + } +} + void LogQuerier::LogQuerierThreadFunc(std::shared_ptr logReader) { cout << "Start log_querier thread!\n" << std::endl; @@ -419,17 +443,13 @@ void LogQuerier::LogQuerierThreadFunc(std::shared_ptr logReader) switch (header->msgType) { case LOG_QUERY_REQUEST: qRstMsg = (LogQueryRequest*) g_tempBuffer; - logReader->queryCondition.levels = qRstMsg->levels; - logReader->queryCondition.types = qRstMsg->types; - logReader->queryCondition.domain = qRstMsg->domain; - logReader->queryCondition.timeBegin = qRstMsg->timeBegin; - logReader->queryCondition.timeEnd = qRstMsg->timeEnd; - HandleLogQueryRequest(logReader, hilogBuffer); + SetCondition(logReader, *qRstMsg); + HandleLogQueryRequest(logReader, *hilogBuffer); break; case NEXT_REQUEST: nRstMsg = (NextRequest*) g_tempBuffer; if (nRstMsg->sendId == SENDIDA) { - HandleNextRequest(logReader, hilogBuffer); + HandleNextRequest(logReader, *hilogBuffer); } break; case MC_REQ_LOG_PERSIST_START: diff --git a/services/hilogd/log_reader.cpp b/services/hilogd/log_reader.cpp index 0bb7b2fa5b3c0dc06c2fbed4ed301aa8cf5e4649..cad3aa62d69c829ab4d90934231c1f11533d658c 100644 --- a/services/hilogd/log_reader.cpp +++ b/services/hilogd/log_reader.cpp @@ -30,10 +30,6 @@ HilogBuffer* LogReader::hilogBuffer = nullptr; LogReader::LogReader() { oldData = {}; - queryCondition.levels = 0; - queryCondition.types = 0; - queryCondition.timeBegin = 0; - queryCondition.timeEnd = 0; isNotified = false; } diff --git a/services/hilogtool/include/hilogtool.h b/services/hilogtool/include/hilogtool.h new file mode 100644 index 0000000000000000000000000000000000000000..a13cfdba55a86990a01740e8da536eb9d27bf69f --- /dev/null +++ b/services/hilogtool/include/hilogtool.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HILOGTOOL_H +#define HILOGTOOL_H + +namespace OHOS { +namespace HiviewDFX { +typedef struct { + uint16_t noBlockMode; + uint8_t nDomain; + uint8_t nNoDomain; + uint8_t nTag; + uint8_t nNoTag; + uint16_t types; + uint16_t levels; + uint16_t headLines; + uint16_t tailLines; + std::string domain; // domain recv + std::string tag; // tag recv + std::string domains[MAX_DOMAINS]; // domains send + std::string tags[MAX_TAGS]; // tags send + uint16_t noTypes; + uint16_t noLevels; + std::string noDomains[MAX_DOMAINS]; + std::string noTags[MAX_TAGS]; + std::string regexArgs; + std::string buffSizeArgs; + std::string logFileCtrlArgs; + std::string compressArgs; + std::string fileSizeArgs; + std::string fileNumArgs; + std::string filePathArgs; + std::string fileNameArgs; + std::string jobIdArgs; + std::string personalArgs; + std::string logClearArgs; + std::string logTypeArgs; + std::string domainArgs; + std::string statisticArgs; + std::string tagArgs; + std::string logLevelArgs; + std::string flowSwitchArgs; + std::string flowQuotaArgs; + std::string pidArgs; + std::string algorithmArgs; +} HilogArgs; +} // namespace HiviewDFX +} // namespace OHOS +#endif diff --git a/services/hilogtool/include/log_controller.h b/services/hilogtool/include/log_controller.h index 39dc381e182d61dd1fcd2ae0dd11019f67c71fc4..2030eac95e9073b91117bcaf9622ecb625694a62 100644 --- a/services/hilogtool/include/log_controller.h +++ b/services/hilogtool/include/log_controller.h @@ -22,6 +22,7 @@ #include #include "hilogtool_msg.h" #include "seq_packet_socket_client.h" +#include "hilogtool.h" namespace OHOS { namespace HiviewDFX { diff --git a/services/hilogtool/log_controller.cpp b/services/hilogtool/log_controller.cpp index 09691bdb45f94b4aac06fda2f6e49221b592f7b2..1fb61fd1c07f8e37403012ac1ee11b004fefe473 100644 --- a/services/hilogtool/log_controller.cpp +++ b/services/hilogtool/log_controller.cpp @@ -151,15 +151,29 @@ void LogQueryRequestOp(SeqPacketSocketClient& controller, const HilogArgs* conte memset_s(&logQueryRequest, sizeof(LogQueryRequest), 0, sizeof(LogQueryRequest)); logQueryRequest.levels = context->levels; logQueryRequest.types = context->types; - if (context->domainArgs != "") { - std::istringstream(context->domainArgs) >> std::hex >> logQueryRequest.domain; - if (logQueryRequest.domain == 0) { - std::cout << "Invalid parameter" << std::endl; - return; + logQueryRequest.nDomain = context->nDomain; + logQueryRequest.nTag = context->nTag; + for (int i = 0; i < context->nDomain; i++) { + std::istringstream(context->domains[i]) >> std::hex >> logQueryRequest.domains[i]; + } + for (int i = 0; i < context->nTag; i++) { + std::istringstream(context->tags[i]) >> std::hex >> logQueryRequest.tags[i]; + } + logQueryRequest.noLevels = context->noLevels; + logQueryRequest.noTypes = context->noTypes; + logQueryRequest.nNoDomain = context->nNoDomain; + for (int i = 0; i < context->nNoDomain; i++) { + std::istringstream(context->noDomains[i]) >> std::hex >> logQueryRequest.noDomains[i]; + } + for (int i = 0; i < context->nNoTag; i++) { + if (context->noTags[i].length() >= MAX_TAG_LEN) { + strncpy_s(logQueryRequest.noTags[i], MAX_TAG_LEN, + context->noTags[i].c_str(), MAX_TAG_LEN - 1); + } else { + strncpy_s(logQueryRequest.noTags[i], context->noTags[i].length() + 1, + context->noTags[i].c_str(), context->noTags[i].length()); } } - logQueryRequest.timeBegin = context->beginTime; - logQueryRequest.timeEnd = context->endTime; SetMsgHead(&logQueryRequest.header, LOG_QUERY_REQUEST, sizeof(LogQueryRequest)-sizeof(MessageHeader)); logQueryRequest.header.version = 0; controller.WriteAll((char*)&logQueryRequest, sizeof(LogQueryRequest)); diff --git a/services/hilogtool/main.cpp b/services/hilogtool/main.cpp index ced850de9c4f294d307b5a73a42e279c2eb6fd2d..0b2edf101a8261f949d73314a17a0c1cda2dacc8 100644 --- a/services/hilogtool/main.cpp +++ b/services/hilogtool/main.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -90,8 +91,6 @@ static void Helper() " query log file writing task query.\n" " start start a log file writing task, see -F -l -n -c for to set more configs,\n" " stop stop a log file writing task.\n" - " -M begintime/endtime/domain/tag/level,--multi-query begintime/endtime/domain/tag/level\n" - " multiple conditions query\n" " -v , --format= options:\n" " time display local time.\n" " color display colorful logs by log level.i.e. \x1B[38;5;231mVERBOSE\n" @@ -103,25 +102,23 @@ static void Helper() " nsec display time by nano sec.\n" " year display the year.\n" " zone display the time zone.\n" + " -b , --baselevel=\n" + " set loggable level.\n" + " \n Types, levels, domains, tags support exclusion query.\n" + " Exclusion query can be done with parameters starting with \"^\" and delimiter \",\".\n" + " Example: \"-t ^core,app\" excludes logs with types core and app.\n" + " Could be used along with other parameters.\n" ); } -static std::time_t Str2Time(const std::string& str, bool isDst = false, - const std::string& format = "%Y-%m-%d_%H:%M:%S") +static int GetTypes(HilogArgs context, const string& typesArgs, bool exclude = false) { - if (str == "") { - return 0; + uint16_t types = 0; + if (exclude) { + types = context.noTypes; } else { - std::tm t = {0}; - t.tm_isdst = isDst ? 1 : 0; - std::istringstream ss(str); - ss >> std::get_time(&t, format.c_str()); - return mktime(&t); + types = context.types; } -} -static int GetTypes(HilogArgs context, string typesArgs) -{ - uint16_t types = context.types; if (typesArgs == "init") { types |= 1< args; HilogArgs context = {sizeof(HilogArgs), 0}; - string typesArgs; - string levelsArgs; char recvBuffer[RECV_BUF_LEN] = {0}; int optIndex = 0; int indexLevel = 0; int indexType = 0; + int indexDomain = 0; + int indexTag = 0; bool noLogOption = false; - + regex delimiter(","); context.noBlockMode = 0; int32_t ret = 0; HilogShowFormat showFormat = OFF_SHOWFORMAT; @@ -189,7 +191,6 @@ int HilogEntry(int argc, char* argv[]) { "tail", required_argument, nullptr, 'z' }, { "format", required_argument, nullptr, 'v' }, { "buffer-size", required_argument, nullptr, 'G' }, - { "multi-query", required_argument, nullptr, 'M' }, { "jobid", required_argument, nullptr, 'j' }, { "flowctrl", required_argument, nullptr, 'Q' }, { "compress", required_argument, nullptr, 'c' }, @@ -240,12 +241,28 @@ int HilogEntry(int argc, char* argv[]) string types(argv[indexType]); indexType++; if (!strstr(types.c_str(), "-")) { - typesArgs += types; - context.types = GetTypes(context, types); + if (types.front() == '^') { + vector v(sregex_token_iterator(types.begin() + 1, types.end(), delimiter, -1), + sregex_token_iterator()); + for (auto s : v) { + context.noTypes = GetTypes(context, s, true); + } + } else { + vector v(sregex_token_iterator(types.begin(), types.end(), delimiter, -1), + sregex_token_iterator()); + for (auto s : v) { + context.types = GetTypes(context, s); + } + } } else { break; } } + if (context.types != 0 && context.noTypes != 0) { + std::cout << "Query condition on both types and excluded types is undefined." << std::endl; + std::cout << "Please remove types or excluded types condition, and try again." << std::endl; + exit(RET_FAIL); + } break; case 'L': indexLevel = optind - 1; @@ -253,45 +270,32 @@ int HilogEntry(int argc, char* argv[]) string levels(argv[indexLevel]); indexLevel++; if (!strstr(levels.c_str(), "-")) { - levelsArgs += levels; - context.levels = GetLevels(context, levels); + if (levels.front() == '^') { + vector v(sregex_token_iterator(levels.begin() + 1, levels.end(), delimiter, -1), + sregex_token_iterator()); + for (auto s : v) { + context.noLevels = GetLevels(context, s, true); + } + } else { + vector v(sregex_token_iterator(levels.begin(), levels.end(), delimiter, -1), + sregex_token_iterator()); + for (auto s : v) { + context.levels = GetLevels(context, s); + } + } } else { break; } } + if (context.levels != 0 && context.noLevels != 0) { + std::cout << "Query condition on both levels and excluded levels is undefined." << std::endl; + std::cout << "Please remove levels or excluded levels condition, and try again." << std::endl; + exit(RET_FAIL); + } break; case 'v': showFormat = HilogFormat(optarg); break; - case 'M':{ - std::vector vecSrc; - std::vector vecSplit; - vecSplit.push_back(optarg); - for (auto src : vecSplit) { - vecSplit.clear(); - int iRet = MultiQuerySplit(src, '/', vecSplit); - if (iRet == 0) { - int idex = 0; - for (auto it : vecSplit) { - vecSrc.push_back(it.c_str()); - idex++; - } - } - if (vecSrc.size() > MULARGS) { - std::cout<<"Invalid parameter"<= MAX_DOMAINS) || (context.nNoDomain >= MAX_DOMAINS)) { + break; + } + std::string domains(argv[indexDomain]); + indexDomain++; + if (!strstr(domains.c_str(), "-")) { + if (domains.front() == '^') { + vector v(sregex_token_iterator(domains.begin() + 1, domains.end(), delimiter, -1), + sregex_token_iterator()); + for (auto s: v) { + context.noDomains[context.nNoDomain++] = s; + } + } else { + vector v(sregex_token_iterator(domains.begin(), domains.end(), delimiter, -1), + sregex_token_iterator()); + for (auto s: v) { + context.domains[context.nDomain++] = s; + context.domainArgs += (s + " "); + } + } + } else { + break; + } + } break; case 's': context.statisticArgs = "query"; @@ -339,7 +368,37 @@ int HilogEntry(int argc, char* argv[]) noLogOption = true; break; case 'T': - context.tagArgs = optarg; + indexTag = optind - 1; + while (indexTag < argc) { + if ((context.nTag >= MAX_TAGS) || (context.nNoTag >= MAX_TAGS)) { + break; + } + std::string tags(argv[indexTag]); + indexTag++; + if (!strstr(tags.c_str(), "-")) { + if (tags.front() == '^') { + vector v(sregex_token_iterator(tags.begin() + 1, tags.end(), delimiter, -1), + sregex_token_iterator()); + for (auto s: v) { + context.noTags[context.nNoTag++] = s; + } + } else { + vector v(sregex_token_iterator(tags.begin(), tags.end(), delimiter, -1), + sregex_token_iterator()); + for (auto s: v) { + context.tags[context.nTag++] = s; + context.tagArgs += (s + " "); + } + } + } else { + break; + } + } + if (context.nTag != 0 && context.nNoTag != 0) { + std::cout << "Query condition on both tags and excluded tags is undefined." << std::endl; + std::cout << "Please remove tags or excluded tags condition, and try again." << std::endl; + exit(RET_FAIL); + } break; case 'b': context.logLevelArgs = optarg; @@ -369,10 +428,10 @@ int HilogEntry(int argc, char* argv[]) exit(-1); } - if (typesArgs == "") { + if (context.types == 0) { context.types = DEFAULT_LOG_TYPE; } - if (levelsArgs == "") { + if (context.levels == 0) { context.levels = DEFAULT_LOG_LEVEL; } if (noLogOption) { @@ -459,6 +518,10 @@ int HilogEntry(int argc, char* argv[]) } } else { LogQueryRequestOp(controller, &context); + context.nDomain = 0; + context.nNoDomain = 0; + context.nTag = 0; + context.nNoTag = 0; } memset_s(recvBuffer, sizeof(recvBuffer), 0, sizeof(recvBuffer));