美文网首页
Paddle-Mobile中的日志打印

Paddle-Mobile中的日志打印

作者: 石器时代小古董 | 来源:发表于2019-06-13 21:36 被阅读0次

编译时添加宏定义

一、Paddle-Mobile 的日志开关

1.Paddle-Mobile 的日志开关在 cmakeList 中进行配置的。
通过 option 定义了日志的开关。如果 WITH_LOGGING 开启,将通过 add_definitions 定义 PADDLE_MOBILE_DEBUG 的宏。

option(WITH_LOGGING     "print logging for debug"        ON)
if(WITH_LOGGING)
    message(STATUS "Debugging mode")
    add_definitions(-DPADDLE_MOBILE_DEBUG)
else()

2.在编译时添加 ANDROID 宏定义

   cmake .. \
        -B"../build/release/${PLATFORM}" \
        .....
        -DANDROID=true \
        -DNET="${NETS}" \
        -D"${ARM_PLATFORM}"=true

也可以在 cmakelist 中添加

IF (op_android MATCHES ON)
    SET(tag android)
    ADD_DEFINITIONS(-DANDROID)
ENDIF()

二、避免引入不需要的库

1.根据宏定义来决定引入什么库

include <vector>
#ifdef PADDLE_MOBILE_DEBUG
#include <cstring>
#include <iostream>
#include <sstream>
#include <string>
#endif

2.如果还定义了 ANDROID,引入Android的日志文件
这样做的好处时可以避免引入不需要的库

#ifdef ANDROID
#include <android/log.h>
#endif

三、日志打印的核心

1.宏定义日志打印方法,简化代码量

#ifdef ANDROID

static const char *ANDROID_LOG_TAG =
    "paddle_mobile LOG built on " __DATE__ " " __TIME__;

#define ANDROIDLOGI(...)                                               \
  __android_log_print(ANDROID_LOG_INFO, ANDROID_LOG_TAG, __VA_ARGS__); \
  fprintf(stderr, "%s\n", __VA_ARGS__);                                \
  fflush(stderr)
.....
#else
#define ANDROIDLOGI(...)
#define ANDROIDLOGW(...)
#define ANDROIDLOGD(...)
#define ANDROIDLOGE(...)

#endif

2.fprintf和fflush
fprintf函数根据输入的格式需求将日志输入到文件中,但是在 Paddle-Mobile 中,fprintf 传入的是 stderr 参数,这样会使 fprintf输出的内容到控制台的屏幕上。
**fflush 强制刷新缓冲区,可以让日志打印内容更快的输出到屏幕上
对 ToLog 对象是友好的,可以让ToLog对象轻松的访问到私有的 buffer_对象

3.日志打印对象
Paddle-Mobile定义了两个日志打印对象(结构体),Print和ToLog,Print是实际调用定义好的宏去打印日志。

1.std::cerr 输出错误类型的信息到控制台
2. ostringstream 可以更加安全的进行类型转换
3.重写了<< 运算符,可以更方便的使用

struct Print {
  friend struct ToLog;

  template <typename T>
  Print &operator<<(T const &value) {
    buffer_ << value;
    return *this;
  }

 private:
  void print(LogLevel level) {
    // buffer_ << std::endl;
    if (level == kLOG_ERROR) {
#ifdef ANDROID
      ANDROIDLOGE(buffer_.str().c_str());
#else
      std::cerr << buffer_.str() << std::endl;
#endif
    } else {
#ifdef ANDROID
      ANDROIDLOGI(buffer_.str().c_str());
#else
      std::cout << buffer_.str() << std::endl;
#endif
    }
  }
  std::ostringstream buffer_;
};

ostringstream的例子

ostringstream oss;//创建一个流

oss<<t;//把值传递如流中

result=oss.str();//获取转换后的字符转并将其写入result

3.ToLog对象

1.explicit防止隐士的赋值
2.重写了<<云算符,并且将输入定义成模板方法,因为这些输入最后是交给 print 对象,而 print 对象最终是交给 ostringsteam 对象,模板类型可以将各种输入更好的交给ostringstream对象以便打印

struct ToLog {
  explicit ToLog(LogLevel level = kLOG_DEBUG, const std::string &info = "")
      : level_(level) {
    unsigned blanks =
        (unsigned)(level > kLOG_DEBUG ? (level - kLOG_DEBUG) * 4 : 1);
    printer_ << logs[level] << " " << info << ":" << std::string(blanks, ' ');
  }

  template <typename T>
  ToLog &operator<<(T const &value) {
    printer_ << value;
    return *this;
  }

  ~ToLog() { printer_.print(level_); }

 private:
  LogLevel level_;
  Print printer_;
};

4.定义了规范的日志打印方式
这种方式会具体定位到某个文件的某一行

#define LOG(level)                                                           \
  if (level > paddle_mobile::log_level) {                                    \
  } else                                                                     \
    paddle_mobile::ToLog(                                                    \
        level, static_cast<const std::stringstream &>(                       \
                   std::stringstream()                                       \
                   << "[file: "                                              \
                   << (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1) \
                                              : __FILE__)                    \
                   << "] [line: " << __LINE__ << "] ")                       \
                   .str())

五、如果没有开启 Debug 开关

Paddle-Mobile 对象上面的所有方法都在没有定义 PADDLE_DEBUG宏时重新定义了一份,保证在没有定义开关时,不会出现任何问题

相关文章

  • Paddle-Mobile中的日志打印

    编译时添加宏定义 一、Paddle-Mobile 的日志开关 1.Paddle-Mobile 的日志开关在 cma...

  • Nacos 大量日志、服务端频繁打印日志、客户端频繁打印日志、日

    日志打印频繁的问题 在老的 Nacos 版本中,往往会有大量的无效日志打印,这些日志的打印会迅速占用完用户的磁盘空...

  • iOS Log打印

    简述 iOS调试中打印日志是一种比较常见的手段,一般都是使用系统的打印日志的方法NSLog,但是这种打印日志的方法...

  • 在学习swift的一些笔记(一)

    -objective-c与swift打印日志的区别 objective-c中的日志打印代码: 第一行代码是打印的格...

  • Log4j

    类中添加属性 作用 打印日志时显示日志所在的类

  • Swift日志打印的正确姿势

    打印日志是程序员调试代码的无上利器,俗话说“不会打印日志的开发不是好码农”。但在发布环境中,日志打印又会影响代码性...

  • 高并发系统谨防被一行日志击垮

    一、同步打印日志中的坑 1.1 高并发场景下 logback 造成线程泄露 调用 logback 去打印日志的时候...

  • 使用log4js打印日志

    使用log4js打印日志 不管在做任何开发的时候,打印日志都是很重要的功能。在Node.js中,最普通的打日志的方...

  • 使用filter_parameter_logging过滤敏感日志

    在rails的日志打印中,我们经常需要对信息进行日志打印过滤,如密码一类的信息。 下面是正常的日志输出: 当我们对...

  • logback学习笔记(上)

    相信任何一位工程师都在代码中写过日志打印代码,也知道日志打印对项目的重要性,有人做过统计代码中的日志占到工程总代码...

网友评论

      本文标题:Paddle-Mobile中的日志打印

      本文链接:https://www.haomeiwen.com/subject/wjuefctx.html