log_trace.h 5.6 KB
Newer Older
G
Grissiom 已提交
1
/*
2
 * Copyright (c) 2006-2018, RT-Thread Development Team
G
Grissiom 已提交
3
 *
4
 * SPDX-License-Identifier: Apache-2.0
G
Grissiom 已提交
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 * Change Logs:
 * Date           Author       Notes
 *                Bernard      the first version
 * 2013-06-26     Grissiom     refactor
 */

#ifndef __LOG_TRACE_H__
#define __LOG_TRACE_H__

#include <rtthread.h>

#define LOG_TRACE_LEVEL_MASK        0x0f
#define LOG_TRACE_LEVEL_NOTRACE     0x00
#define LOG_TRACE_LEVEL_ERROR       0x01
G
Grissiom 已提交
20 21 22 23
#define LOG_TRACE_LEVEL_WARNING     0x03
#define LOG_TRACE_LEVEL_INFO        0x05
#define LOG_TRACE_LEVEL_VERBOSE     0x07
#define LOG_TRACE_LEVEL_DEBUG       0x09
G
Grissiom 已提交
24 25
#define LOG_TRACE_LEVEL_ALL         0x0f

26 27 28 29 30 31 32 33 34 35 36 37 38 39
#if defined(LOG_TRACE_USING_LEVEL_NOTRACE)
#define LOG_TRACE_LEVEL_DEFAULT     LOG_TRACE_LEVEL_NOTRACE
#elif defined(LOG_TRACE_USING_LEVEL_ERROR)
#define LOG_TRACE_LEVEL_DEFAULT     LOG_TRACE_LEVEL_ERROR
#elif defined(LOG_TRACE_USING_LEVEL_WARNING)
#define LOG_TRACE_LEVEL_DEFAULT     LOG_TRACE_LEVEL_WARNING
#elif defined(LOG_TRACE_USING_LEVEL_INFO)
#define LOG_TRACE_LEVEL_DEFAULT     LOG_TRACE_LEVEL_INFO
#elif defined(LOG_TRACE_USING_LEVEL_VERBOSE)
#define LOG_TRACE_LEVEL_DEFAULT     LOG_TRACE_LEVEL_VERBOSE
#elif defined(LOG_TRACE_USING_LEVEL_DEBUG)
#define LOG_TRACE_LEVEL_DEFAULT     LOG_TRACE_LEVEL_DEBUG
#else
#define LOG_TRACE_LEVEL_DEFAULT     LOG_TRACE_LEVEL_INFO
G
Grissiom 已提交
40 41 42
#endif

#define LOG_TRACE_ERROR             "<1>"
G
Grissiom 已提交
43 44 45 46
#define LOG_TRACE_WARNING           "<3>"
#define LOG_TRACE_INFO              "<5>"
#define LOG_TRACE_VERBOSE           "<7>"
#define LOG_TRACE_DEBUG             "<9>"
G
Grissiom 已提交
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89

#define LOG_TRACE_OPT_NOTS          0x10    /* no timestamp */
#define LOG_TRACE_OPT_LN            0x20    /* terminate the current line */

#define LOG_TRACE_CTRL_FLUSH        0x10
#define LOG_TRACE_CTRL_RESET        0x11
#define LOG_TRACE_CTRL_DUMP         0x12

//#define LOG_TRACE_USE_LONGNAME

#ifndef LOG_TRACE_BUFSZ
#define LOG_TRACE_BUFSZ RT_CONSOLEBUF_SIZE
#endif

/** maximum number of sessions that can be registered to the log_trace system
 */
#ifndef LOG_TRACE_MAX_SESSION
#define LOG_TRACE_MAX_SESSION 16
#endif

#ifdef LOG_TRACE_USE_LONGNAME
typedef rt_uint64_t log_trace_idnum_t;
#else
typedef rt_uint32_t log_trace_idnum_t;
#endif

/* use a integer to represent a string to avoid strcmp. Even 4 chars
 * should be enough for most of the cases.
 * NOTE: take care when converting the name string to id number, you
 * can trapped in endianness.
 */
union log_trace_id {
    char name[sizeof(log_trace_idnum_t)];
    log_trace_idnum_t num;
};

struct log_trace_session
{
    union log_trace_id id;
    rt_uint8_t lvl;
};

/** initialize the log_trace system */
90
int log_trace_init(void);
G
Grissiom 已提交
91 92 93 94 95

/** register a session.
 *
 * @return RT_EOK on success. -RT_EFULL if there is no space for registration.
 */
96
rt_err_t log_trace_register_session(const struct log_trace_session *session);
G
Grissiom 已提交
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130

/** find a session with name
 *
 * The name is not enclosed by parenthesis([]).
 *
 * @return RT_NULL if there is no such a session.
 */
struct log_trace_session* log_trace_session_find(const char *name);

/** set the log level of the default session. */
void log_trace_set_level(rt_uint8_t level);

/** set the log level of the session */
void log_trace_session_set_level(
        struct log_trace_session *session, rt_uint8_t level);

/** log according to the format
 *
 * the format of log_trace is: "<level>[name]log messages".  It will output
 * "[systick][name]log messages" When there is no session named name, the
 * default session will be used.
 *
 * We have keep the level tag before the name tag because we don't print put
 * the level tag to the output and it's easier to implement if we place the
 * level tag in the very beginning.
 */
void log_trace(const char *fmt, ...);

/** log into session.
 *
 * the format of log_trace is: "<level>log messages".  It will output
 * "[systick][name]log messages". The name is the name of the session. It is
 * faster than bare log_trace.
 */
131
void log_session(const struct log_trace_session *session, const char *fmt, ...);
G
Grissiom 已提交
132

G
Grissiom 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
extern void __logtrace_vfmtout(const struct log_trace_session *session,
                               const char *fmt,
                               va_list argptr);

rt_inline void __logtrace_fmtout(const struct log_trace_session *session,
                                     const char *fmt, ...)
{
    va_list args;

    va_start(args, fmt);
    __logtrace_vfmtout(session, fmt, args);
    va_end(args);
}

/**
 * log with numeric level
 *
 * The prototype of this function is:
 *
 * void log_session_lvl(struct log_trace_session *session,
 *                      int lvl,
 *                      const char *fmt, ...);
 *
 * If the @session is const and @level is greater than @session->lvl, the whole
 * function will be optimized out. This is suitable for performance critical
 * places where in most cases, the log is turned off by level.
 */
#define log_session_lvl(session, level, fmt, ...)       \
    do {                                                \
        if ((level) > (session)->lvl)                   \
        {                                               \
            break;                                      \
        }                                               \
        __logtrace_fmtout(session, fmt, ##__VA_ARGS__); \
    } while (0)

G
Grissiom 已提交
169 170 171 172 173 174 175 176 177 178
/* here comes the global part. All sessions share the some output backend. */

/** get the backend device */
rt_device_t log_trace_get_device(void);

/** set the backend device */
rt_err_t log_trace_set_device(const char *device_name);

void log_trace_flush(void);

179
#ifdef RT_USING_DFS
G
Grissiom 已提交
180 181 182 183
/** set the backend to file */
void log_trace_set_file(const char *filename);

void log_trace_file_init(const char *filename);
184
#endif /* RT_USING_DFS */
G
Grissiom 已提交
185 186 187

#endif