diff --git a/frameworks/libhilog/utils/include/log_print.h b/frameworks/libhilog/utils/include/log_print.h index a84cdc582fb4baa66e51c3ecfa62e5f3716d5956..fbd3c62c8f0c2eee248ef050f8787bd1c38b5f3e 100644 --- a/frameworks/libhilog/utils/include/log_print.h +++ b/frameworks/libhilog/utils/include/log_print.h @@ -39,6 +39,7 @@ struct LogFormat { FormatTimeAccu timeAccuFormat; bool year; bool zone; + bool wrap; }; void LogPrintWithFormat(const LogContent& content, const LogFormat& format, std::ostream& out = std::cout); diff --git a/frameworks/libhilog/utils/include/log_utils.h b/frameworks/libhilog/utils/include/log_utils.h index 464fe848bd9c2ce305e3015a21d6fc61f820c9b5..5b0ad29fc23041358375674cfb19899f0a87a33d 100644 --- a/frameworks/libhilog/utils/include/log_utils.h +++ b/frameworks/libhilog/utils/include/log_utils.h @@ -105,6 +105,7 @@ uint32_t GetPPidByPid(uint32_t pid); uint64_t GenerateHash(const char *p, size_t size); void PrintErrorno(int err); int WaitingToDo(int max, const std::string& path, std::function func); +std::wstring StringToWstring(const std::string& input); } // namespace HiviewDFX } // namespace OHOS #endif // LOG_UTILS_H \ No newline at end of file diff --git a/frameworks/libhilog/utils/log_print.cpp b/frameworks/libhilog/utils/log_print.cpp index b8b278ea884e1bae0816208083faed4f6405836e..3c7be480deeba6a28a2723c15fbb6939a9a5e62a 100644 --- a/frameworks/libhilog/utils/log_print.cpp +++ b/frameworks/libhilog/utils/log_print.cpp @@ -44,6 +44,7 @@ static constexpr int NSEC_WIDTH = 9; static constexpr int PID_WIDTH = 5; static constexpr int DOMAIN_WIDTH = 5; static constexpr int DOMAIN_SHORT_MASK = 0xFFFFF; +static constexpr int PREFIX_LEN = 42; static inline int GetColor(uint16_t level) { @@ -142,6 +143,16 @@ static void PrintLogPrefix(const LogContent& content, const LogFormat& format, s } } +static void AdaptWrap(const LogContent& content, const LogFormat& format, std::ostream& out) +{ + if (format.wrap) { + out << setfill(' '); + out << std::setw(PREFIX_LEN + StringToWstring(content.tag).length()) << " "; + } else { + PrintLogPrefix(content, format, out); + } +} + void LogPrintWithFormat(const LogContent& content, const LogFormat& format, std::ostream& out) { // set colorful log @@ -151,6 +162,9 @@ void LogPrintWithFormat(const LogContent& content, const LogFormat& format, std: const char *pHead = content.log; const char *pScan = content.log; + if (*pScan != '\0') { + PrintLogPrefix(content, format, out); + } // split the log content by '\n', and add log prefix(datetime, pid, tid....) to each new line while (*pScan != '\0') { if (*pScan == '\n') { @@ -162,15 +176,16 @@ void LogPrintWithFormat(const LogContent& content, const LogFormat& format, std: } tmp[(MAX_LOG_LEN - 1) > len ? len : (MAX_LOG_LEN -1)] = '\0'; if (tmp[0] != '\0') { - PrintLogPrefix(content, format, out); out << tmp << endl; } pHead = pScan + 1; + if (pHead[0] != '\0' && pHead[0] != '\n') { + AdaptWrap(content, format, out); + } } pScan++; } if (pHead[0] != '\0') { - PrintLogPrefix(content, format, out); out << pHead; } diff --git a/frameworks/libhilog/utils/log_utils.cpp b/frameworks/libhilog/utils/log_utils.cpp index d483a5c28735b56b46747581a2d4649d2ca6a525..be9ab9f6c8ae710959bacba176880ec0eba32870 100644 --- a/frameworks/libhilog/utils/log_utils.cpp +++ b/frameworks/libhilog/utils/log_utils.cpp @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include #include #include #include @@ -519,5 +520,11 @@ int WaitingToDo(int max, const string& path, function f } } } + +std::wstring StringToWstring(const std::string& input) +{ + std::wstring_convert> converter; + return converter.from_bytes(input); +} } // namespace HiviewDFX } // namespace OHOS diff --git a/services/hilogtool/main.cpp b/services/hilogtool/main.cpp index dfb3224dd46c5d56d5dad5837a91ed204836ea95..9a941c70c1196ceddeb4de6dc488c7439c05ede1 100644 --- a/services/hilogtool/main.cpp +++ b/services/hilogtool/main.cpp @@ -17,7 +17,7 @@ #include #include #include - +#include #include #include #include @@ -34,6 +34,29 @@ namespace OHOS { namespace HiviewDFX { using namespace std; +static void FormatHelper() +{ + cout + << " -v , --format=" << endl + << " Show logs in different formats, options are:" << endl + << " color or colour display colorful logs by log level.i.e." << endl + << " \x1B[38;5;75mDEBUG \x1B[38;5;40mINFO \x1B[38;5;166mWARN" + << " \x1B[38;5;196mERROR \x1B[38;5;226mFATAL\x1B[0m" << endl + << " time format options are(single accepted):" << endl + << " time display local time, this is default." << endl + << " epoch display the time from 1970/1/1." << endl + << " monotonic display the cpu time from bootup." << endl + << " time accuracy format options are(single accepted):" << endl + << " msec display time by millisecond, this is default." << endl + << " usec display time by microsecond." << endl + << " nsec display time by nanosecond." << endl + << " year display the year when -v time is specified." << endl + << " zone display the time zone when -v time is specified." << endl + << " wrap display the log without prefix when a log line is wrapped." << endl + << " Different types of formats can be combined, such as:" << endl + << " -v color -v time -v msec -v year -v zone." << endl; +} + static void QueryHelper() { cout @@ -71,24 +94,8 @@ static void QueryHelper() << " Don't show specific domain/domains logs with format: ^pid1,pid2,pid3" << endl << " Max pid count is " << MAX_PIDS << "." << endl << " -e , --regex=" << endl - << " Show the logs which match the regular expression ." << endl - << " -v , --format=" << endl - << " Show logs in different formats, options are:" << endl - << " color or colour display colorful logs by log level.i.e." << endl - << " \x1B[38;5;75mDEBUG \x1B[38;5;40mINFO \x1B[38;5;166mWARN" - << " \x1B[38;5;196mERROR \x1B[38;5;226mFATAL\x1B[0m" << endl - << " time format options are(single accepted):" << endl - << " time display local time, this is default." << endl - << " epoch display the time from 1970/1/1." << endl - << " monotonic display the cpu time from bootup." << endl - << " time accuracy format options are(single accepted):" << endl - << " msec display time by millisecond, this is default." << endl - << " usec display time by microsecond." << endl - << " nsec display time by nanosecond." << endl - << " year display the year when -v time is specified." << endl - << " zone display the time zone when -v time is specified." << endl - << " Different types of formats can be combined, such as:" << endl - << " -v color -v time -v msec -v year -v zone." << endl; + << " Show the logs which match the regular expression ." << endl; + FormatHelper(); } static void ClearHelper() @@ -319,6 +326,7 @@ struct HilogArgs { FormatTimeAccu timeAccuFormat; bool year; bool zone; + bool wrap; bool noBlock; uint16_t tailLines; @@ -326,7 +334,7 @@ struct HilogArgs { fileName(""), buffSize(0), jobId(0), fileSize(0), levels(0), stream(""), fileNum(0), blackPid(false), pidCount(0), pids { 0 }, types(0), blackTag(false), tagCount(0), tags { "" }, colorful(false), timeFormat(FormatTime::INVALID), timeAccuFormat(FormatTimeAccu::INVALID), year(false), zone(false), - noBlock(false), tailLines(0) {} + wrap(false), noBlock(false), tailLines(0) {} void ToOutputRqst(OutputRqst& rqst) { @@ -425,7 +433,8 @@ static int QueryLogHandler(HilogArgs& context, const char *arg) .timeAccuFormat = ((context.timeAccuFormat == FormatTimeAccu::INVALID) ? FormatTimeAccu::MSEC : context.timeAccuFormat), .year = context.year, - .zone = context.zone + .zone = context.zone, + .wrap = context.wrap }; LogPrintWithFormat(content, format); return static_cast(SUCCESS_CONTINUE); @@ -788,42 +797,73 @@ static int TagHandler(HilogArgs& context, const char *arg) return RET_SUCCESS; } +static int TimeHandler(HilogArgs& context, FormatTime value) +{ + if (context.timeFormat != FormatTime::INVALID) { + return ERR_DUPLICATE_OPTION; + } + context.timeFormat = value; + return RET_SUCCESS; +} + +static int TimeAccuHandler(HilogArgs& context, FormatTimeAccu value) +{ + if (context.timeAccuFormat != FormatTimeAccu::INVALID) { + return ERR_DUPLICATE_OPTION; + } + context.timeAccuFormat = value; + return RET_SUCCESS; +} + static int FormatHandler(HilogArgs& context, const char *arg) { - string strArg = arg; - if (strArg == "color" || strArg == "colour") { - context.colorful = true; - } else if (strArg == "time" || strArg == "epoch" || strArg == "monotonic") { - if (context.timeFormat != FormatTime::INVALID) { - return ERR_DUPLICATE_OPTION; - } - if (strArg == "time") { - context.timeFormat = FormatTime::TIME; - } else if (strArg == "epoch") { - context.timeFormat = FormatTime::EPOCH; - } else if (strArg == "monotonic") { - context.timeFormat = FormatTime::MONOTONIC; - } - } else if (strArg == "msec" || strArg == "usec" || strArg == "nsec") { - if (context.timeAccuFormat != FormatTimeAccu::INVALID) { - return ERR_DUPLICATE_OPTION; - } - if (strArg == "msec") { - context.timeAccuFormat = FormatTimeAccu::MSEC; - } else if (strArg == "usec") { - context.timeAccuFormat = FormatTimeAccu::USEC; - } else if (strArg == "nsec") { - context.timeAccuFormat = FormatTimeAccu::NSEC; - } - } else if (strArg == "year") { - context.year = true; - } else if (strArg == "zone") { - context.zone = true; - tzset(); - } else { + static std::unordered_map> handlers = { + {"color", [] (HilogArgs& context, int value) { + context.colorful = true; + return RET_SUCCESS; + }}, + {"colour", [] (HilogArgs& context, int value) { + context.colorful = true; + return RET_SUCCESS; + }}, + {"time", [] (HilogArgs& context, int value) { + return TimeHandler(context, FormatTime::TIME); + }}, + {"epoch", [] (HilogArgs& context, int value) { + return TimeHandler(context, FormatTime::EPOCH); + }}, + {"monotonic", [] (HilogArgs& context, int value) { + return TimeHandler(context, FormatTime::MONOTONIC); + }}, + {"msec", [] (HilogArgs& context, int value) { + return TimeAccuHandler(context, FormatTimeAccu::MSEC); + }}, + {"usec", [] (HilogArgs& context, int value) { + return TimeAccuHandler(context, FormatTimeAccu::USEC); + }}, + {"nsec", [] (HilogArgs& context, int value) { + return TimeAccuHandler(context, FormatTimeAccu::NSEC); + }}, + {"year", [] (HilogArgs& context, int value) { + context.year = true; + return RET_SUCCESS; + }}, + {"zone", [] (HilogArgs& context, int value) { + context.zone = true; + tzset(); + return RET_SUCCESS; + }}, + {"wrap", [] (HilogArgs& context, int value) { + context.wrap = true; + return RET_SUCCESS; + }}, + }; + + auto handler = handlers.find(arg); + if (handler == handlers.end() || handler->second == nullptr) { return ERR_INVALID_ARGUMENT; } - return RET_SUCCESS; + return handler->second(context, 0); } static int PersistTaskStart(HilogArgs& context)