tlog.c 27.9 KB
Newer Older
H
hzcheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

S
slguan 已提交
16
#define _DEFAULT_SOURCE
S
log  
Shengliang Guan 已提交
17
#include "tlog.h"
H
Hongze Cheng 已提交
18
#include "os.h"
19
#include "tconfig.h"
dengyihao's avatar
dengyihao 已提交
20
#include "tutil.h"
D
dapan1121 已提交
21 22
#include "tjson.h"
#include "tglobal.h"
L
Liu Jicong 已提交
23

D
dapan1121 已提交
24
#define LOG_MAX_LINE_SIZE             (10024)
S
Shengliang Guan 已提交
25
#define LOG_MAX_LINE_BUFFER_SIZE      (LOG_MAX_LINE_SIZE + 3)
26
#define LOG_MAX_LINE_DUMP_SIZE        (1024 * 1024)
S
Shengliang Guan 已提交
27
#define LOG_MAX_LINE_DUMP_BUFFER_SIZE (LOG_MAX_LINE_DUMP_SIZE + 3)
S
slguan 已提交
28

S
ulog  
Shengliang Guan 已提交
29 30
#define LOG_FILE_NAME_LEN    300
#define LOG_DEFAULT_BUF_SIZE (20 * 1024 * 1024)  // 20MB
H
hzcheng 已提交
31

S
ulog  
Shengliang Guan 已提交
32 33 34 35 36
#define LOG_DEFAULT_INTERVAL 25
#define LOG_INTERVAL_STEP    5
#define LOG_MIN_INTERVAL     5
#define LOG_MAX_INTERVAL     25
#define LOG_MAX_WAIT_MSEC    1000
D
fix bug  
dapan1121 已提交
37

S
slguan 已提交
38
#define LOG_BUF_BUFFER(x) ((x)->buffer)
S
ulog  
Shengliang Guan 已提交
39 40 41 42
#define LOG_BUF_START(x)  ((x)->buffStart)
#define LOG_BUF_END(x)    ((x)->buffEnd)
#define LOG_BUF_SIZE(x)   ((x)->buffSize)
#define LOG_BUF_MUTEX(x)  ((x)->buffMutex)
S
slguan 已提交
43

H
hzcheng 已提交
44
typedef struct {
dengyihao's avatar
dengyihao 已提交
45
  char         *buffer;
46 47 48 49 50 51 52
  int32_t       buffStart;
  int32_t       buffEnd;
  int32_t       buffSize;
  int32_t       minBuffSize;
  TdFilePtr     pFile;
  int32_t       stop;
  TdThread      asyncThread;
wafwerar's avatar
wafwerar 已提交
53
  TdThreadMutex buffMutex;
H
hzcheng 已提交
54 55
} SLogBuff;

S
slguan 已提交
56
typedef struct {
57 58 59 60 61 62 63
  int32_t       fileNum;
  int32_t       maxLines;
  int32_t       lines;
  int32_t       flag;
  int32_t       openInProgress;
  pid_t         pid;
  char          logName[LOG_FILE_NAME_LEN];
dengyihao's avatar
dengyihao 已提交
64
  SLogBuff     *logHandle;
wafwerar's avatar
wafwerar 已提交
65
  TdThreadMutex logMutex;
S
slguan 已提交
66 67
} SLogObj;

68
extern SConfig *tsCfg;
dengyihao's avatar
dengyihao 已提交
69 70 71 72
static int8_t   tsLogInited = 0;
static SLogObj  tsLogObj = {.fileNum = 1};
static int64_t  tsAsyncLogLostLines = 0;
static int32_t  tsWriteInterval = LOG_DEFAULT_INTERVAL;
dengyihao's avatar
dengyihao 已提交
73
static int32_t  tsDaylightActive; /* Currently in daylight saving time. */
L
Liu Jicong 已提交
74

S
Shengliang Guan 已提交
75
bool    tsLogEmbedded = 0;
S
Shengliang Guan 已提交
76
bool    tsAsyncLog = true;
S
Shengliang Guan 已提交
77
bool    tsAssert = true;
S
Shengliang Guan 已提交
78
int32_t tsNumOfLogLines = 10000000;
S
Shengliang Guan 已提交
79
int32_t tsLogKeepDays = 0;
S
Shengliang Guan 已提交
80
LogFp   tsLogFp = NULL;
S
Shengliang Guan 已提交
81 82 83 84
int64_t tsNumOfErrorLogs = 0;
int64_t tsNumOfInfoLogs = 0;
int64_t tsNumOfDebugLogs = 0;
int64_t tsNumOfTraceLogs = 0;
D
fix bug  
dapan1121 已提交
85

S
Shengliang Guan 已提交
86
// log
S
Shengliang Guan 已提交
87 88 89
int32_t dDebugFlag = 131;
int32_t vDebugFlag = 131;
int32_t mDebugFlag = 131;
S
Shengliang Guan 已提交
90 91
int32_t cDebugFlag = 131;
int32_t jniDebugFlag = 131;
S
Shengliang Guan 已提交
92
int32_t tmrDebugFlag = 131;
S
Shengliang Guan 已提交
93
int32_t uDebugFlag = 131;
S
Shengliang Guan 已提交
94 95
int32_t rpcDebugFlag = 131;
int32_t qDebugFlag = 131;
S
Shengliang Guan 已提交
96 97
int32_t wDebugFlag = 131;
int32_t sDebugFlag = 131;
S
Shengliang Guan 已提交
98
int32_t tsdbDebugFlag = 131;
H
Hongze Cheng 已提交
99
int32_t tdbDebugFlag = 131;
S
Shengliang Guan 已提交
100 101 102 103
int32_t tqDebugFlag = 131;
int32_t fsDebugFlag = 131;
int32_t metaDebugFlag = 131;
int32_t udfDebugFlag = 131;
C
Cary Xu 已提交
104
int32_t smaDebugFlag = 131;
S
Shengliang Guan 已提交
105
int32_t idxDebugFlag = 131;
D
dapan1121 已提交
106

D
fix bug  
dapan1121 已提交
107
int64_t dbgEmptyW = 0;
D
fix bug  
dapan1121 已提交
108 109 110
int64_t dbgWN = 0;
int64_t dbgSmallWN = 0;
int64_t dbgBigWN = 0;
D
fix bug  
dapan1121 已提交
111 112
int64_t dbgWSize = 0;

dengyihao's avatar
dengyihao 已提交
113
static void     *taosAsyncOutputLog(void *param);
114
static int32_t   taosPushLogBuffer(SLogBuff *pLogBuf, const char *msg, int32_t msgLen);
S
slguan 已提交
115
static SLogBuff *taosLogBuffNew(int32_t bufSize);
116
static void      taosCloseLogByFd(TdFilePtr pFile);
S
slguan 已提交
117 118
static int32_t   taosOpenLogFile(char *fn, int32_t maxLines, int32_t maxFileNum);

dengyihao's avatar
dengyihao 已提交
119 120 121 122 123
static FORCE_INLINE void taosUpdateDaylight() {
  struct tm      Tm, *ptm;
  struct timeval timeSecs;
  taosGetTimeOfDay(&timeSecs);
  time_t curTime = timeSecs.tv_sec;
124
  ptm = taosLocalTime(&curTime, &Tm, NULL);
dengyihao's avatar
dengyihao 已提交
125 126 127 128
  tsDaylightActive = ptm->tm_isdst;
}
static FORCE_INLINE int32_t taosGetDaylight() { return tsDaylightActive; }

S
slguan 已提交
129
static int32_t taosStartLog() {
wafwerar's avatar
wafwerar 已提交
130 131 132
  TdThreadAttr threadAttr;
  taosThreadAttrInit(&threadAttr);
  if (taosThreadCreate(&(tsLogObj.logHandle->asyncThread), &threadAttr, taosAsyncOutputLog, tsLogObj.logHandle) != 0) {
H
hzcheng 已提交
133 134
    return -1;
  }
wafwerar's avatar
wafwerar 已提交
135
  taosThreadAttrDestroy(&threadAttr);
H
hzcheng 已提交
136 137 138
  return 0;
}

S
Shengliang Guan 已提交
139
int32_t taosInitLog(const char *logName, int32_t maxFiles) {
S
Shengliang Guan 已提交
140
  if (atomic_val_compare_exchange_8(&tsLogInited, 0, 1) != 0) return 0;
S
osenv  
Shengliang Guan 已提交
141
  osUpdate();
S
Shengliang Guan 已提交
142

S
Shengliang Guan 已提交
143
  char fullName[PATH_MAX] = {0};
dengyihao's avatar
dengyihao 已提交
144 145 146 147 148
  if (strlen(tsLogDir) != 0) {
    snprintf(fullName, PATH_MAX, "%s" TD_DIRSEP "%s", tsLogDir, logName);
  } else {
    snprintf(fullName, PATH_MAX, "%s", logName);
  }
dengyihao's avatar
dengyihao 已提交
149
  taosUpdateDaylight();
S
Shengliang Guan 已提交
150

S
ulog  
Shengliang Guan 已提交
151
  tsLogObj.logHandle = taosLogBuffNew(LOG_DEFAULT_BUF_SIZE);
S
slguan 已提交
152
  if (tsLogObj.logHandle == NULL) return -1;
S
Shengliang Guan 已提交
153
  if (taosOpenLogFile(fullName, tsNumOfLogLines, maxFiles) < 0) return -1;
H
hzcheng 已提交
154 155 156 157
  if (taosStartLog() < 0) return -1;
  return 0;
}

S
slguan 已提交
158 159 160 161
static void taosStopLog() {
  if (tsLogObj.logHandle) {
    tsLogObj.logHandle->stop = 1;
  }
H
hzcheng 已提交
162 163
}

S
slguan 已提交
164
void taosCloseLog() {
165 166 167 168
  if (tsLogObj.logHandle != NULL) {
    taosStopLog();
    if (tsLogObj.logHandle != NULL && taosCheckPthreadValid(tsLogObj.logHandle->asyncThread)) {
      taosThreadJoin(tsLogObj.logHandle->asyncThread, NULL);
169
      taosThreadClear(&tsLogObj.logHandle->asyncThread);
170 171 172 173 174 175 176 177 178 179 180
    }
    tsLogInited = 0;

    taosThreadMutexDestroy(&tsLogObj.logHandle->buffMutex);
    taosCloseFile(&tsLogObj.logHandle->pFile);
    taosMemoryFreeClear(tsLogObj.logHandle->buffer);
    memset(&tsLogObj.logHandle->buffer, 0, sizeof(tsLogObj.logHandle->buffer));
    taosThreadMutexDestroy(&tsLogObj.logMutex);
    taosMemoryFreeClear(tsLogObj.logHandle);
    memset(&tsLogObj.logHandle, 0, sizeof(tsLogObj.logHandle));
    tsLogObj.logHandle = NULL;
S
slguan 已提交
181
  }
H
hzcheng 已提交
182 183
}

184 185
static bool taosLockLogFile(TdFilePtr pFile) {
  if (pFile == NULL) return false;
H
hzcheng 已提交
186

S
slguan 已提交
187
  if (tsLogObj.fileNum > 1) {
188
    int32_t ret = taosLockFile(pFile);
H
hzcheng 已提交
189 190 191 192 193 194 195 196
    if (ret == 0) {
      return true;
    }
  }

  return false;
}

197 198
static void taosUnLockLogFile(TdFilePtr pFile) {
  if (pFile == NULL) return;
H
hzcheng 已提交
199

S
slguan 已提交
200
  if (tsLogObj.fileNum > 1) {
201
    taosUnLockFile(pFile);
H
hzcheng 已提交
202 203 204
  }
}

S
TD-1263  
Shengliang Guan 已提交
205
static void taosKeepOldLog(char *oldName) {
S
TD-1574  
Shengliang Guan 已提交
206
  if (tsLogKeepDays == 0) return;
S
TD-1263  
Shengliang Guan 已提交
207

S
TD-1263  
Shengliang Guan 已提交
208
  int64_t fileSec = taosGetTimestampSec();
S
TD-1263  
Shengliang Guan 已提交
209
  char    fileName[LOG_FILE_NAME_LEN + 20];
S
TD-1263  
Shengliang Guan 已提交
210
  snprintf(fileName, LOG_FILE_NAME_LEN + 20, "%s.%" PRId64, tsLogObj.logName, fileSec);
S
TD-1263  
Shengliang Guan 已提交
211

A
Alex Duan 已提交
212
  (void)taosRenameFile(oldName, fileName);
213

S
TD-1574  
Shengliang Guan 已提交
214 215 216 217
  if (tsLogKeepDays < 0) {
    char compressFileName[LOG_FILE_NAME_LEN + 20];
    snprintf(compressFileName, LOG_FILE_NAME_LEN + 20, "%s.%" PRId64 ".gz", tsLogObj.logName, fileSec);
    if (taosCompressFile(fileName, compressFileName) == 0) {
218
      (void)taosRemoveFile(fileName);
S
TD-1574  
Shengliang Guan 已提交
219 220 221
    }
  }

S
os env  
Shengliang Guan 已提交
222
  taosRemoveOldFiles(tsLogDir, TABS(tsLogKeepDays));
S
TD-1263  
Shengliang Guan 已提交
223 224
}

S
slguan 已提交
225
static void *taosThreadToOpenNewFile(void *param) {
S
TD-1263  
Shengliang Guan 已提交
226 227
  char keepName[LOG_FILE_NAME_LEN + 20];
  sprintf(keepName, "%s.%d", tsLogObj.logName, tsLogObj.flag);
H
hzcheng 已提交
228

S
slguan 已提交
229 230
  tsLogObj.flag ^= 1;
  tsLogObj.lines = 0;
S
TD-1263  
Shengliang Guan 已提交
231
  char name[LOG_FILE_NAME_LEN + 20];
S
slguan 已提交
232
  sprintf(name, "%s.%d", tsLogObj.logName, tsLogObj.flag);
H
hzcheng 已提交
233

S
Shengliang Guan 已提交
234
  taosUmaskFile(0);
H
hzcheng 已提交
235

236
  TdFilePtr pFile = taosOpenFile(name, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
237
  if (pFile == NULL) {
238 239
    tsLogObj.openInProgress = 0;
    tsLogObj.lines = tsLogObj.maxLines - 1000;
240
    uError("open new log file fail! reason:%s, reuse lastlog", strerror(errno));
H
Hui Li 已提交
241 242
    return NULL;
  }
S
TD-1263  
Shengliang Guan 已提交
243

244 245
  taosLockLogFile(pFile);
  (void)taosLSeekFile(pFile, 0, SEEK_SET);
H
hzcheng 已提交
246

247 248
  TdFilePtr pOldFile = tsLogObj.logHandle->pFile;
  tsLogObj.logHandle->pFile = pFile;
S
slguan 已提交
249 250
  tsLogObj.lines = 0;
  tsLogObj.openInProgress = 0;
wafwerar's avatar
wafwerar 已提交
251
  taosSsleep(20);
252
  taosCloseLogByFd(pOldFile);
L
Liu Jicong 已提交
253

S
TD-1263  
Shengliang Guan 已提交
254 255
  uInfo("   new log file:%d is opened", tsLogObj.flag);
  uInfo("==================================");
S
TD-1263  
Shengliang Guan 已提交
256 257
  taosKeepOldLog(keepName);

H
hzcheng 已提交
258 259 260
  return NULL;
}

S
slguan 已提交
261
static int32_t taosOpenNewLogFile() {
wafwerar's avatar
wafwerar 已提交
262
  taosThreadMutexLock(&tsLogObj.logMutex);
H
hzcheng 已提交
263

S
slguan 已提交
264 265
  if (tsLogObj.lines > tsLogObj.maxLines && tsLogObj.openInProgress == 0) {
    tsLogObj.openInProgress = 1;
H
hzcheng 已提交
266

267
    uInfo("open new log file ......");
268
    TdThread     thread;
wafwerar's avatar
wafwerar 已提交
269 270 271
    TdThreadAttr attr;
    taosThreadAttrInit(&attr);
    taosThreadAttrSetDetachState(&attr, PTHREAD_CREATE_DETACHED);
H
hzcheng 已提交
272

wafwerar's avatar
wafwerar 已提交
273 274
    taosThreadCreate(&thread, &attr, taosThreadToOpenNewFile, NULL);
    taosThreadAttrDestroy(&attr);
H
hzcheng 已提交
275 276
  }

wafwerar's avatar
wafwerar 已提交
277
  taosThreadMutexUnlock(&tsLogObj.logMutex);
H
hzcheng 已提交
278 279 280 281

  return 0;
}

S
slguan 已提交
282 283 284
void taosResetLog() {
  char lastName[LOG_FILE_NAME_LEN + 20];
  sprintf(lastName, "%s.%d", tsLogObj.logName, tsLogObj.flag);
H
hzcheng 已提交
285 286

  // force create a new log file
S
slguan 已提交
287
  tsLogObj.lines = tsLogObj.maxLines + 10;
H
hzcheng 已提交
288 289

  taosOpenNewLogFile();
290
  (void)taosRemoveFile(lastName);
H
hzcheng 已提交
291

292 293
  uInfo("==================================");
  uInfo("   reset log file ");
H
hzcheng 已提交
294 295
}

S
slguan 已提交
296
static bool taosCheckFileIsOpen(char *logFileName) {
297 298
  TdFilePtr pFile = taosOpenFile(logFileName, TD_FILE_WRITE);
  if (pFile == NULL) {
299 300 301 302 303 304
    if (errno == ENOENT) {
      return false;
    } else {
      printf("\nfailed to open log file:%s, reason:%s\n", logFileName, strerror(errno));
      return true;
    }
H
hzcheng 已提交
305 306
  }

307 308 309
  if (taosLockLogFile(pFile)) {
    taosUnLockLogFile(pFile);
    taosCloseFile(&pFile);
H
hzcheng 已提交
310 311
    return false;
  } else {
312
    taosCloseFile(&pFile);
H
hzcheng 已提交
313 314 315 316
    return true;
  }
}

S
slguan 已提交
317 318 319
static void taosGetLogFileName(char *fn) {
  if (tsLogObj.fileNum > 1) {
    for (int32_t i = 0; i < tsLogObj.fileNum; i++) {
H
hzcheng 已提交
320 321
      char fileName[LOG_FILE_NAME_LEN];

H
Haojun Liao 已提交
322
      snprintf(fileName, LOG_FILE_NAME_LEN, "%s%d.0", fn, i);
H
hzcheng 已提交
323 324
      bool file1open = taosCheckFileIsOpen(fileName);

H
Haojun Liao 已提交
325
      snprintf(fileName, LOG_FILE_NAME_LEN, "%s%d.1", fn, i);
H
hzcheng 已提交
326 327 328
      bool file2open = taosCheckFileIsOpen(fileName);

      if (!file1open && !file2open) {
H
Haojun Liao 已提交
329
        snprintf(tsLogObj.logName, LOG_FILE_NAME_LEN, "%s%d", fn, i);
H
hzcheng 已提交
330 331 332 333 334
        return;
      }
    }
  }

H
Hui Li 已提交
335 336 337
  if (strlen(fn) < LOG_FILE_NAME_LEN) {
    strcpy(tsLogObj.logName, fn);
  }
H
hzcheng 已提交
338 339
}

S
slguan 已提交
340
static int32_t taosOpenLogFile(char *fn, int32_t maxLines, int32_t maxFileNum) {
S
slguan 已提交
341 342
#ifdef WINDOWS
  /*
L
Liu Jicong 已提交
343 344 345
   * always set maxFileNum to 1
   * means client log filename is unique in windows
   */
S
slguan 已提交
346 347 348
  maxFileNum = 1;
#endif

S
Shengliang Guan 已提交
349 350 351
  char    name[LOG_FILE_NAME_LEN + 50] = "\0";
  int32_t logstat0_mtime, logstat1_mtime;
  int32_t size;
H
hzcheng 已提交
352

S
slguan 已提交
353 354
  tsLogObj.maxLines = maxLines;
  tsLogObj.fileNum = maxFileNum;
H
hzcheng 已提交
355 356
  taosGetLogFileName(fn);

H
Hui Li 已提交
357 358 359 360
  if (strlen(fn) < LOG_FILE_NAME_LEN + 50 - 2) {
    strcpy(name, fn);
    strcat(name, ".0");
  }
S
Shengliang Guan 已提交
361
  bool log0Exist = taosStatFile(name, NULL, &logstat0_mtime) >= 0;
H
hzcheng 已提交
362

S
TD-1263  
Shengliang Guan 已提交
363 364 365 366
  if (strlen(fn) < LOG_FILE_NAME_LEN + 50 - 2) {
    strcpy(name, fn);
    strcat(name, ".1");
  }
S
Shengliang Guan 已提交
367 368
  bool log1Exist = taosStatFile(name, NULL, &logstat1_mtime) >= 0;

H
hzcheng 已提交
369
  // if none of the log files exist, open 0, if both exists, open the old one
S
TD-1263  
Shengliang Guan 已提交
370 371 372
  if (!log0Exist && !log1Exist) {
    tsLogObj.flag = 0;
  } else if (!log1Exist) {
S
slguan 已提交
373
    tsLogObj.flag = 0;
S
TD-1263  
Shengliang Guan 已提交
374 375
  } else if (!log0Exist) {
    tsLogObj.flag = 1;
H
hzcheng 已提交
376
  } else {
S
Shengliang Guan 已提交
377
    tsLogObj.flag = (logstat0_mtime > logstat1_mtime) ? 0 : 1;
H
hzcheng 已提交
378 379
  }

H
Hui Li 已提交
380 381
  char fileName[LOG_FILE_NAME_LEN + 50] = "\0";
  sprintf(fileName, "%s.%d", tsLogObj.logName, tsLogObj.flag);
wafwerar's avatar
wafwerar 已提交
382
  taosThreadMutexInit(&tsLogObj.logMutex, NULL);
H
hzcheng 已提交
383

S
Shengliang Guan 已提交
384
  taosUmaskFile(0);
385
  tsLogObj.logHandle->pFile = taosOpenFile(fileName, TD_FILE_CREATE | TD_FILE_WRITE);
H
hzcheng 已提交
386

387
  if (tsLogObj.logHandle->pFile == NULL) {
H
Hui Li 已提交
388
    printf("\nfailed to open log file:%s, reason:%s\n", fileName, strerror(errno));
H
hzcheng 已提交
389 390
    return -1;
  }
391
  taosLockLogFile(tsLogObj.logHandle->pFile);
H
hzcheng 已提交
392 393

  // only an estimate for number of lines
S
Shengliang Guan 已提交
394
  int64_t filesize = 0;
395
  if (taosFStatFile(tsLogObj.logHandle->pFile, &filesize, NULL) < 0) {
H
Hui Li 已提交
396
    printf("\nfailed to fstat log file:%s, reason:%s\n", fileName, strerror(errno));
H
Hui Li 已提交
397 398
    return -1;
  }
S
Shengliang Guan 已提交
399
  size = (int32_t)filesize;
S
slguan 已提交
400
  tsLogObj.lines = size / 60;
H
hzcheng 已提交
401

402
  taosLSeekFile(tsLogObj.logHandle->pFile, 0, SEEK_END);
H
hzcheng 已提交
403 404

  sprintf(name, "==================================================\n");
405
  taosWriteFile(tsLogObj.logHandle->pFile, name, (uint32_t)strlen(name));
H
hzcheng 已提交
406
  sprintf(name, "                new log file                      \n");
407
  taosWriteFile(tsLogObj.logHandle->pFile, name, (uint32_t)strlen(name));
H
hzcheng 已提交
408
  sprintf(name, "==================================================\n");
409
  taosWriteFile(tsLogObj.logHandle->pFile, name, (uint32_t)strlen(name));
H
hzcheng 已提交
410 411 412 413

  return 0;
}

414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
static void taosUpdateLogNums(ELogLevel level) {
  switch (level) {
    case DEBUG_ERROR:
      atomic_add_fetch_64(&tsNumOfErrorLogs, 1);
      break;
    case DEBUG_INFO:
      atomic_add_fetch_64(&tsNumOfInfoLogs, 1);
      break;
    case DEBUG_DEBUG:
      atomic_add_fetch_64(&tsNumOfDebugLogs, 1);
      break;
    case DEBUG_DUMP:
    case DEBUG_TRACE:
      atomic_add_fetch_64(&tsNumOfTraceLogs, 1);
      break;
    default:
      break;
  }
}

S
Shengliang Guan 已提交
434
static inline int32_t taosBuildLogHead(char *buffer, const char *flags) {
H
hzcheng 已提交
435 436 437
  struct tm      Tm, *ptm;
  struct timeval timeSecs;

S
Shengliang Guan 已提交
438
  taosGetTimeOfDay(&timeSecs);
S
Shengliang Guan 已提交
439
  time_t curTime = timeSecs.tv_sec;
440
  ptm = taosLocalTime(&curTime, &Tm, NULL);
S
slguan 已提交
441

S
Shengliang Guan 已提交
442 443 444
  return sprintf(buffer, "%02d/%02d %02d:%02d:%02d.%06d %08" PRId64 " %s", ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour,
                 ptm->tm_min, ptm->tm_sec, (int32_t)timeSecs.tv_usec, taosGetSelfPthreadId(), flags);
}
H
hzcheng 已提交
445

S
Shengliang Guan 已提交
446
static inline void taosPrintLogImp(ELogLevel level, int32_t dflag, const char *buffer, int32_t len) {
wafwerar's avatar
wafwerar 已提交
447
  if ((dflag & DEBUG_FILE) && tsLogObj.logHandle && tsLogObj.logHandle->pFile != NULL && osLogSpaceAvailable()) {
448
    taosUpdateLogNums(level);
449 450 451
#if 0 
    // DEBUG_FATAL and DEBUG_ERROR are duplicated
    // fsync will cause thread blocking and may also generate log misalignment in case of asyncLog
B
Benguang Zhao 已提交
452
    if (tsAsyncLog && level != DEBUG_FATAL) {
S
slguan 已提交
453
      taosPushLogBuffer(tsLogObj.logHandle, buffer, len);
H
hzcheng 已提交
454
    } else {
455
      taosWriteFile(tsLogObj.logHandle->pFile, buffer, len);
B
Benguang Zhao 已提交
456 457 458
      if (level == DEBUG_FATAL) {
        taosFsyncFile(tsLogObj.logHandle->pFile);
      }
H
hzcheng 已提交
459
    }
460 461 462 463 464 465 466
#else
    if (tsAsyncLog) {
      taosPushLogBuffer(tsLogObj.logHandle, buffer, len);
    } else {
      taosWriteFile(tsLogObj.logHandle->pFile, buffer, len);
    }
#endif
H
hzcheng 已提交
467

S
slguan 已提交
468 469
    if (tsLogObj.maxLines > 0) {
      atomic_add_fetch_32(&tsLogObj.lines, 1);
S
Shengliang Guan 已提交
470 471 472
      if ((tsLogObj.lines > tsLogObj.maxLines) && (tsLogObj.openInProgress == 0)) {
        taosOpenNewLogFile();
      }
H
hzcheng 已提交
473 474 475
    }
  }

476
  if (dflag & DEBUG_SCREEN) {
477 478
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
S
Shengliang Guan 已提交
479
    write(1, buffer, (uint32_t)len);
480
#pragma GCC diagnostic pop
481
  }
H
hzcheng 已提交
482 483
}

S
Shengliang Guan 已提交
484
void taosPrintLog(const char *flags, ELogLevel level, int32_t dflag, const char *format, ...) {
S
Shengliang Guan 已提交
485
  if (!(dflag & DEBUG_FILE) && !(dflag & DEBUG_SCREEN)) return;
S
slguan 已提交
486

S
Shengliang Guan 已提交
487 488
  char    buffer[LOG_MAX_LINE_BUFFER_SIZE];
  int32_t len = taosBuildLogHead(buffer, flags);
H
hzcheng 已提交
489

S
Shengliang Guan 已提交
490 491
  va_list argpointer;
  va_start(argpointer, format);
S
Shengliang Guan 已提交
492
  int32_t writeLen = len + vsnprintf(buffer + len, LOG_MAX_LINE_BUFFER_SIZE - len, format, argpointer);
S
Shengliang Guan 已提交
493
  va_end(argpointer);
H
hzcheng 已提交
494

S
Shengliang Guan 已提交
495 496 497
  if (writeLen > LOG_MAX_LINE_SIZE) writeLen = LOG_MAX_LINE_SIZE;
  buffer[writeLen++] = '\n';
  buffer[writeLen] = 0;
H
hzcheng 已提交
498

S
Shengliang Guan 已提交
499 500 501 502 503 504
  taosPrintLogImp(level, dflag, buffer, writeLen);

  if (tsLogFp && level <= DEBUG_INFO) {
    buffer[writeLen - 1] = 0;
    (*tsLogFp)(taosGetTimestampMs(), level, buffer + len);
  }
H
hzcheng 已提交
505 506
}

507
void taosPrintLongString(const char *flags, ELogLevel level, int32_t dflag, const char *format, ...) {
S
os env  
Shengliang Guan 已提交
508
  if (!osLogSpaceAvailable()) return;
S
Shengliang Guan 已提交
509
  if (!(dflag & DEBUG_FILE) && !(dflag & DEBUG_SCREEN)) return;
S
slguan 已提交
510

dengyihao's avatar
dengyihao 已提交
511
  char   *buffer = taosMemoryMalloc(LOG_MAX_LINE_DUMP_BUFFER_SIZE);
S
Shengliang Guan 已提交
512
  int32_t len = taosBuildLogHead(buffer, flags);
H
hzcheng 已提交
513

S
Shengliang Guan 已提交
514
  va_list argpointer;
H
hzcheng 已提交
515
  va_start(argpointer, format);
S
Shengliang Guan 已提交
516
  len += vsnprintf(buffer + len, LOG_MAX_LINE_DUMP_BUFFER_SIZE - len, format, argpointer);
H
hzcheng 已提交
517 518
  va_end(argpointer);

S
Shengliang Guan 已提交
519
  if (len > LOG_MAX_LINE_DUMP_SIZE) len = LOG_MAX_LINE_DUMP_SIZE;
H
hzcheng 已提交
520 521 522
  buffer[len++] = '\n';
  buffer[len] = 0;

S
Shengliang Guan 已提交
523
  taosPrintLogImp(level, dflag, buffer, len);
524
  taosMemoryFree(buffer);
S
Shengliang Guan 已提交
525
}
L
Liu Jicong 已提交
526

S
Shengliang Guan 已提交
527 528 529
void taosDumpData(unsigned char *msg, int32_t len) {
  if (!osLogSpaceAvailable()) return;
  taosUpdateLogNums(DEBUG_DUMP);
H
hzcheng 已提交
530

531
  char    temp[256] = {0};
S
Shengliang Guan 已提交
532 533 534 535 536 537 538 539 540 541 542
  int32_t i, pos = 0, c = 0;

  for (i = 0; i < len; ++i) {
    sprintf(temp + pos, "%02x ", msg[i]);
    c++;
    pos += 3;
    if (c >= 16) {
      temp[pos++] = '\n';
      taosWriteFile(tsLogObj.logHandle->pFile, temp, (uint32_t)pos);
      c = 0;
      pos = 0;
H
hzcheng 已提交
543 544 545
    }
  }

S
Shengliang Guan 已提交
546 547 548
  temp[pos++] = '\n';

  taosWriteFile(tsLogObj.logHandle->pFile, temp, (uint32_t)pos);
H
hzcheng 已提交
549 550
}

551 552 553 554
static void taosCloseLogByFd(TdFilePtr pFile) {
  if (pFile != NULL) {
    taosUnLockLogFile(pFile);
    taosCloseFile(&pFile);
H
hzcheng 已提交
555 556 557
  }
}

S
slguan 已提交
558
static SLogBuff *taosLogBuffNew(int32_t bufSize) {
559
  SLogBuff *pLogBuf = NULL;
H
hzcheng 已提交
560

561 562
  pLogBuf = taosMemoryCalloc(1, sizeof(SLogBuff));
  if (pLogBuf == NULL) return NULL;
H
hzcheng 已提交
563

564 565
  LOG_BUF_BUFFER(pLogBuf) = taosMemoryMalloc(bufSize);
  if (LOG_BUF_BUFFER(pLogBuf) == NULL) goto _err;
H
hzcheng 已提交
566

567 568 569 570
  LOG_BUF_START(pLogBuf) = LOG_BUF_END(pLogBuf) = 0;
  LOG_BUF_SIZE(pLogBuf) = bufSize;
  pLogBuf->minBuffSize = bufSize / 10;
  pLogBuf->stop = 0;
H
hzcheng 已提交
571

572 573
  if (taosThreadMutexInit(&LOG_BUF_MUTEX(pLogBuf), NULL) < 0) goto _err;
  // tsem_init(&(pLogBuf->buffNotEmpty), 0, 0);
H
hzcheng 已提交
574

575
  return pLogBuf;
H
hzcheng 已提交
576 577

_err:
578 579
  taosMemoryFreeClear(LOG_BUF_BUFFER(pLogBuf));
  taosMemoryFreeClear(pLogBuf);
H
hzcheng 已提交
580 581 582
  return NULL;
}

583
static void taosCopyLogBuffer(SLogBuff *pLogBuf, int32_t start, int32_t end, const char *msg, int32_t msgLen) {
D
fix bug  
dapan1121 已提交
584
  if (start > end) {
585
    memcpy(LOG_BUF_BUFFER(pLogBuf) + end, msg, msgLen);
D
fix bug  
dapan1121 已提交
586
  } else {
587 588 589
    if (LOG_BUF_SIZE(pLogBuf) - end < msgLen) {
      memcpy(LOG_BUF_BUFFER(pLogBuf) + end, msg, LOG_BUF_SIZE(pLogBuf) - end);
      memcpy(LOG_BUF_BUFFER(pLogBuf), msg + LOG_BUF_SIZE(pLogBuf) - end, msgLen - LOG_BUF_SIZE(pLogBuf) + end);
D
fix bug  
dapan1121 已提交
590
    } else {
591
      memcpy(LOG_BUF_BUFFER(pLogBuf) + end, msg, msgLen);
D
fix bug  
dapan1121 已提交
592 593
    }
  }
594
  LOG_BUF_END(pLogBuf) = (LOG_BUF_END(pLogBuf) + msgLen) % LOG_BUF_SIZE(pLogBuf);
D
fix bug  
dapan1121 已提交
595 596
}

597
static int32_t taosPushLogBuffer(SLogBuff *pLogBuf, const char *msg, int32_t msgLen) {
L
Liu Jicong 已提交
598 599 600
  int32_t        start = 0;
  int32_t        end = 0;
  int32_t        remainSize = 0;
D
fix bug  
dapan1121 已提交
601
  static int64_t lostLine = 0;
H
Haojun Liao 已提交
602
  char           tmpBuf[128] = {0};
L
Liu Jicong 已提交
603
  int32_t        tmpBufLen = 0;
H
hzcheng 已提交
604

605
  if (pLogBuf == NULL || pLogBuf->stop) return -1;
H
hzcheng 已提交
606

607 608 609
  taosThreadMutexLock(&LOG_BUF_MUTEX(pLogBuf));
  start = LOG_BUF_START(pLogBuf);
  end = LOG_BUF_END(pLogBuf);
H
hzcheng 已提交
610

611
  remainSize = (start > end) ? (start - end - 1) : (start + LOG_BUF_SIZE(pLogBuf) - end - 1);
H
hzcheng 已提交
612

D
fix bug  
dapan1121 已提交
613
  if (lostLine > 0) {
H
Haojun Liao 已提交
614
    snprintf(tmpBuf, tListLen(tmpBuf), "...Lost %" PRId64 " lines here...\n", lostLine);
D
dapan1121 已提交
615
    tmpBufLen = (int32_t)strlen(tmpBuf);
D
fix bug  
dapan1121 已提交
616 617 618 619
  }

  if (remainSize <= msgLen || ((lostLine > 0) && (remainSize <= (msgLen + tmpBufLen)))) {
    lostLine++;
S
Shengliang Guan 已提交
620
    tsAsyncLogLostLines++;
621
    taosThreadMutexUnlock(&LOG_BUF_MUTEX(pLogBuf));
H
hzcheng 已提交
622 623 624
    return -1;
  }

D
fix bug  
dapan1121 已提交
625
  if (lostLine > 0) {
626
    taosCopyLogBuffer(pLogBuf, start, end, tmpBuf, tmpBufLen);
D
fix bug  
dapan1121 已提交
627
    lostLine = 0;
H
hzcheng 已提交
628
  }
D
fix bug  
dapan1121 已提交
629

630
  taosCopyLogBuffer(pLogBuf, LOG_BUF_START(pLogBuf), LOG_BUF_END(pLogBuf), msg, msgLen);
H
hzcheng 已提交
631

L
Liu Jicong 已提交
632
  // int32_t w = atomic_sub_fetch_32(&waitLock, 1);
D
fix bug  
dapan1121 已提交
633
  /*
634 635
  if (w <= 0 || ((remainSize - msgLen - tmpBufLen) < (LOG_BUF_SIZE(pLogBuf) * 4 /5))) {
    tsem_post(&(pLogBuf->buffNotEmpty));
D
fix bug  
dapan1121 已提交
636 637 638
    dbgPostN++;
  } else {
    dbgNoPostN++;
D
fix bug  
dapan1121 已提交
639
  }
D
fix bug  
dapan1121 已提交
640
  */
H
hzcheng 已提交
641

642
  taosThreadMutexUnlock(&LOG_BUF_MUTEX(pLogBuf));
H
hzcheng 已提交
643 644 645 646

  return 0;
}

647
static int32_t taosGetLogRemainSize(SLogBuff *pLogBuf, int32_t start, int32_t end) {
D
fix bug  
dapan1121 已提交
648
  int32_t rSize = end - start;
H
hzcheng 已提交
649

650
  return rSize >= 0 ? rSize : LOG_BUF_SIZE(pLogBuf) + rSize;
D
fix bug  
dapan1121 已提交
651
}
H
hzcheng 已提交
652

653
static void taosWriteLog(SLogBuff *pLogBuf) {
D
fix bu  
dapan1121 已提交
654
  static int32_t lastDuration = 0;
L
Liu Jicong 已提交
655 656 657
  int32_t        remainChecked = 0;
  int32_t        start, end, pollSize;

D
fix bug  
dapan1121 已提交
658
  do {
D
fix bu  
dapan1121 已提交
659
    if (remainChecked == 0) {
660 661
      start = LOG_BUF_START(pLogBuf);
      end = LOG_BUF_END(pLogBuf);
D
fix bu  
dapan1121 已提交
662 663 664

      if (start == end) {
        dbgEmptyW++;
S
Shengliang Guan 已提交
665
        tsWriteInterval = LOG_MAX_INTERVAL;
D
fix bu  
dapan1121 已提交
666 667
        return;
      }
H
hzcheng 已提交
668

669 670
      pollSize = taosGetLogRemainSize(pLogBuf, start, end);
      if (pollSize < pLogBuf->minBuffSize) {
S
Shengliang Guan 已提交
671
        lastDuration += tsWriteInterval;
D
fix bug  
dapan1121 已提交
672
        if (lastDuration < LOG_MAX_WAIT_MSEC) {
D
fix bu  
dapan1121 已提交
673 674 675
          break;
        }
      }
D
fix bug  
dapan1121 已提交
676

D
fix bu  
dapan1121 已提交
677 678 679 680
      lastDuration = 0;
    }

    if (start < end) {
681
      taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf) + start, pollSize);
H
hzcheng 已提交
682
    } else {
683 684
      int32_t tsize = LOG_BUF_SIZE(pLogBuf) - start;
      taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf) + start, tsize);
D
fix bug  
dapan1121 已提交
685

686
      taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf), end);
H
hzcheng 已提交
687
    }
D
fix bug  
dapan1121 已提交
688 689

    dbgWN++;
L
Liu Jicong 已提交
690 691
    dbgWSize += pollSize;

692
    if (pollSize < pLogBuf->minBuffSize) {
D
fix bug  
dapan1121 已提交
693
      dbgSmallWN++;
S
Shengliang Guan 已提交
694 695
      if (tsWriteInterval < LOG_MAX_INTERVAL) {
        tsWriteInterval += LOG_INTERVAL_STEP;
D
fix bug  
dapan1121 已提交
696
      }
697
    } else if (pollSize > LOG_BUF_SIZE(pLogBuf) / 3) {
D
fix bug  
dapan1121 已提交
698
      dbgBigWN++;
S
Shengliang Guan 已提交
699
      tsWriteInterval = LOG_MIN_INTERVAL;
700
    } else if (pollSize > LOG_BUF_SIZE(pLogBuf) / 4) {
S
Shengliang Guan 已提交
701 702
      if (tsWriteInterval > LOG_MIN_INTERVAL) {
        tsWriteInterval -= LOG_INTERVAL_STEP;
D
fix bug  
dapan1121 已提交
703
      }
D
fix bug  
dapan1121 已提交
704 705
    }

706
    LOG_BUF_START(pLogBuf) = (LOG_BUF_START(pLogBuf) + pollSize) % LOG_BUF_SIZE(pLogBuf);
D
fix bug  
dapan1121 已提交
707

708 709
    start = LOG_BUF_START(pLogBuf);
    end = LOG_BUF_END(pLogBuf);
D
fix bu  
dapan1121 已提交
710

711 712
    pollSize = taosGetLogRemainSize(pLogBuf, start, end);
    if (pollSize < pLogBuf->minBuffSize) {
D
fix bug  
dapan1121 已提交
713 714 715
      break;
    }

S
Shengliang Guan 已提交
716
    tsWriteInterval = LOG_MIN_INTERVAL;
D
fix bu  
dapan1121 已提交
717 718

    remainChecked = 1;
L
Liu Jicong 已提交
719
  } while (1);
H
hzcheng 已提交
720 721
}

S
slguan 已提交
722
static void *taosAsyncOutputLog(void *param) {
723
  SLogBuff *pLogBuf = (SLogBuff *)param;
H
Haojun Liao 已提交
724
  setThreadName("log");
wafwerar's avatar
wafwerar 已提交
725
  int32_t count = 0;
dengyihao's avatar
dengyihao 已提交
726
  int32_t updateCron = 0;
H
hzcheng 已提交
727
  while (1) {
wafwerar's avatar
wafwerar 已提交
728
    count += tsWriteInterval;
dengyihao's avatar
dengyihao 已提交
729
    updateCron++;
S
Shengliang Guan 已提交
730
    taosMsleep(tsWriteInterval);
wafwerar's avatar
wafwerar 已提交
731 732 733 734
    if (count > 1000) {
      osUpdate();
      count = 0;
    }
H
hzcheng 已提交
735 736

    // Polling the buffer
737
    taosWriteLog(pLogBuf);
H
hzcheng 已提交
738

dengyihao's avatar
dengyihao 已提交
739 740 741 742 743
    if (updateCron >= 3600 * 24 * 40 / 2) {
      taosUpdateDaylight();
      updateCron = 0;
    }

744
    if (pLogBuf->stop) break;
H
hzcheng 已提交
745 746 747 748
  }

  return NULL;
}
S
Shengliang Guan 已提交
749

750
bool taosAssertDebug(bool condition, const char *file, int32_t line, const char *format, ...) {
S
Shengliang Guan 已提交
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
  if (condition) return false;

  const char *flags = "UTL FATAL ";
  ELogLevel   level = DEBUG_FATAL;
  int32_t     dflag = 255;  // tsLogEmbedded ? 255 : uDebugFlag
  char        buffer[LOG_MAX_LINE_BUFFER_SIZE];
  int32_t     len = taosBuildLogHead(buffer, flags);

  va_list argpointer;
  va_start(argpointer, format);
  len = len + vsnprintf(buffer + len, LOG_MAX_LINE_BUFFER_SIZE - len, format, argpointer);
  va_end(argpointer);
  buffer[len++] = '\n';
  buffer[len] = 0;
  taosPrintLogImp(1, 255, buffer, len);

  taosPrintLog(flags, level, dflag, "tAssert at file %s:%d exit:%d", file, line, tsAssert);
D
dapan1121 已提交
768
  taosPrintTrace(flags, level, dflag, -1);
S
Shengliang Guan 已提交
769 770

  if (tsAssert) {
771
    // taosCloseLog();
S
Shengliang Guan 已提交
772 773 774 775 776 777 778 779 780 781
    taosMsleep(300);

#ifdef NDEBUG
    abort();
#else
    assert(0);
#endif
  }

  return true;
D
dapan1121 已提交
782 783
}

D
dapan1121 已提交
784 785 786 787 788 789 790 791 792 793 794 795
int32_t taosGenCrashJsonMsg(int signum, char** pMsg, int64_t clusterId, int64_t startTime) {
  SJson* pJson = tjsonCreateObject();
  if (pJson == NULL) return -1;
  char tmp[4096] = {0};

  tjsonAddDoubleToObject(pJson, "reportVersion", 1);

  tjsonAddIntegerToObject(pJson, "clusterId", clusterId);
  tjsonAddIntegerToObject(pJson, "startTime", startTime);

  taosGetFqdn(tmp);  
  tjsonAddStringToObject(pJson, "fqdn", tmp);
D
dapan1121 已提交
796
  
D
dapan1121 已提交
797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823
  tjsonAddIntegerToObject(pJson, "pid", taosGetPId());

  taosGetAppName(tmp, NULL);
  tjsonAddStringToObject(pJson, "appName", tmp);  

  if (taosGetOsReleaseName(tmp, sizeof(tmp)) == 0) {
    tjsonAddStringToObject(pJson, "os", tmp);
  }

  float numOfCores = 0;
  if (taosGetCpuInfo(tmp, sizeof(tmp), &numOfCores) == 0) {
    tjsonAddStringToObject(pJson, "cpuModel", tmp);
    tjsonAddDoubleToObject(pJson, "numOfCpu", numOfCores);
  } else {
    tjsonAddDoubleToObject(pJson, "numOfCpu", tsNumOfCores);
  }

  snprintf(tmp, sizeof(tmp), "%" PRId64 " kB", tsTotalMemoryKB);
  tjsonAddStringToObject(pJson, "memory", tmp);

  tjsonAddStringToObject(pJson, "version", version);
  tjsonAddStringToObject(pJson, "buildInfo", buildinfo);
  tjsonAddStringToObject(pJson, "gitInfo", gitinfo);

  tjsonAddIntegerToObject(pJson, "crashSig", signum);
  tjsonAddIntegerToObject(pJson, "crashTs", taosGetTimestampUs());

D
dapan1121 已提交
824 825
#ifdef _TD_DARWIN_64
  taosLogTraceToBuf(tmp, sizeof(tmp), 4);
D
dapan1121 已提交
826
#elif !defined(WINDOWS)
D
dapan1121 已提交
827
  taosLogTraceToBuf(tmp, sizeof(tmp), 3);
D
dapan 已提交
828 829 830 831
#else
  taosLogTraceToBuf(tmp, sizeof(tmp), 8);
#endif

D
dapan1121 已提交
832
  tjsonAddStringToObject(pJson, "stackInfo", tmp);
D
dapan1121 已提交
833
  
D
dapan1121 已提交
834 835 836 837 838 839 840 841 842 843
  char* pCont = tjsonToString(pJson);
  tjsonDelete(pJson);

  *pMsg = pCont;

  return TSDB_CODE_SUCCESS;
}


void taosLogCrashInfo(char* nodeType, char* pMsg, int64_t msgLen, int signum, void *sigInfo) {
D
dapan1121 已提交
844 845 846
  const char *flags = "UTL FATAL ";
  ELogLevel   level = DEBUG_FATAL;
  int32_t     dflag = 255;
D
dapan1121 已提交
847 848 849 850 851 852 853 854
  char filepath[PATH_MAX] = {0};
  TdFilePtr pFile = NULL;

  if (pMsg && msgLen > 0) {
    snprintf(filepath, sizeof(filepath), "%s%s.%sCrashLog", tsLogDir, TD_DIRSEP, nodeType);

    pFile = taosOpenFile(filepath, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_APPEND);
    if (pFile == NULL) {
855
      terrno = TAOS_SYSTEM_ERROR(errno);
D
dapan1121 已提交
856 857 858 859 860 861 862 863 864
      taosPrintLog(flags, level, dflag, "failed to open file:%s since %s", filepath, terrstr());
      goto _return;
    }

    taosLockFile(pFile);

    int64_t writeSize = taosWriteFile(pFile, &msgLen, sizeof(msgLen));
    if (sizeof(msgLen) != writeSize) {
      taosUnLockFile(pFile);
D
dapan1121 已提交
865
      taosPrintLog(flags, level, dflag, "failed to write len to file:%s,%p wlen:%" PRId64 " tlen:%lu since %s", 
D
dapan1121 已提交
866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885
          filepath, pFile, writeSize, sizeof(msgLen), terrstr());
      goto _return;
    }

    writeSize = taosWriteFile(pFile, pMsg, msgLen);
    if (msgLen != writeSize) {
      taosUnLockFile(pFile);
      taosPrintLog(flags, level, dflag, "failed to write file:%s,%p wlen:%" PRId64 " tlen:%" PRId64 " since %s", 
          filepath, pFile, writeSize, msgLen, terrstr());
      goto _return;
    }

    taosUnLockFile(pFile);
  }

_return:

  if (pFile) taosCloseFile(&pFile);

  terrno = TAOS_SYSTEM_ERROR(errno);
D
dapan1121 已提交
886
  taosPrintLog(flags, level, dflag, "crash signal is %d", signum);
D
dapan1121 已提交
887 888 889

#ifdef _TD_DARWIN_64
  taosPrintTrace(flags, level, dflag, 4);
D
dapan1121 已提交
890
#elif !defined(WINDOWS)
D
dapan1121 已提交
891 892
  taosPrintLog(flags, level, dflag, "sender PID:%d cmdline:%s", ((siginfo_t *)sigInfo)->si_pid,
        taosGetCmdlineByPID(((siginfo_t *)sigInfo)->si_pid));
D
dapan1121 已提交
893
  taosPrintTrace(flags, level, dflag, 3);
D
dapan 已提交
894 895 896
#else
  taosPrintTrace(flags, level, dflag, 8);
#endif
D
dapan1121 已提交
897

D
dapan1121 已提交
898 899
  taosMemoryFree(pMsg);
}
D
dapan1121 已提交
900

D
dapan1121 已提交
901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945
void taosReadCrashInfo(char* filepath, char** pMsg, int64_t* pMsgLen, TdFilePtr* pFd) {
  const char *flags = "UTL FATAL ";
  ELogLevel   level = DEBUG_FATAL;
  int32_t     dflag = 255;
  TdFilePtr   pFile = NULL;
  bool        truncateFile = false;
  char*       buf = NULL;

  if (NULL == *pFd) {
    int64_t filesize = 0;
    if (taosStatFile(filepath, &filesize, NULL) < 0) {
      if (ENOENT == errno) {
        return;
      }

      terrno = TAOS_SYSTEM_ERROR(errno);
      taosPrintLog(flags, level, dflag, "failed to stat file:%s since %s", filepath, terrstr());
      return;
    }

    if (filesize <= 0) {
      return;
    }

    pFile = taosOpenFile(filepath, TD_FILE_READ|TD_FILE_WRITE);
    if (pFile == NULL) {
      if (ENOENT == errno) {
        return;
      }

      terrno = TAOS_SYSTEM_ERROR(errno);
      taosPrintLog(flags, level, dflag, "failed to open file:%s since %s", filepath, terrstr());
      return;
    }
    
    taosLockFile(pFile);
  } else {
    pFile = *pFd;
  }

  int64_t msgLen = 0;
  int64_t readSize = taosReadFile(pFile, &msgLen, sizeof(msgLen));
  if (sizeof(msgLen) != readSize) {
    truncateFile = true;
    if (readSize < 0) {
D
dapan1121 已提交
946
      taosPrintLog(flags, level, dflag, "failed to read len from file:%s,%p wlen:%" PRId64 " tlen:%lu since %s", 
D
dapan1121 已提交
947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992
          filepath, pFile, readSize, sizeof(msgLen), terrstr());
    }
    goto _return;
  }

  buf = taosMemoryMalloc(msgLen);
  if (NULL == buf) {
    taosPrintLog(flags, level, dflag, "failed to malloc buf, size:%" PRId64, msgLen);
    goto _return;
  }
  
  readSize = taosReadFile(pFile, buf, msgLen);
  if (msgLen != readSize) {
    truncateFile = true;
    taosPrintLog(flags, level, dflag, "failed to read file:%s,%p wlen:%" PRId64 " tlen:%" PRId64 " since %s", 
        filepath, pFile, readSize, msgLen, terrstr());
    goto _return;
  }

  *pMsg = buf;
  *pMsgLen = msgLen;
  *pFd = pFile;

  return;

_return:

  if (truncateFile) {
    taosFtruncateFile(pFile, 0);
  }
  taosUnLockFile(pFile);
  taosCloseFile(&pFile);
  taosMemoryFree(buf);

  *pMsg = NULL;
  *pMsgLen = 0;
  *pFd = NULL;
}

void taosReleaseCrashLogFile(TdFilePtr pFile, bool truncateFile) {
  if (truncateFile) {
    taosFtruncateFile(pFile, 0);
  }
  
  taosUnLockFile(pFile);
  taosCloseFile(&pFile);
D
dapan1121 已提交
993 994
}

995 996 997 998 999 1000 1001 1002 1003
#ifdef NDEBUG
bool taosAssertRelease(bool condition) {
  if (condition) return false;

  const char *flags = "UTL FATAL ";
  ELogLevel   level = DEBUG_FATAL;
  int32_t     dflag = 255;  // tsLogEmbedded ? 255 : uDebugFlag

  taosPrintLog(flags, level, dflag, "tAssert called in release mode, exit:%d", tsAssert);
S
Shengliang Guan 已提交
1004
  taosPrintTrace(flags, level, dflag, 0);
1005 1006 1007 1008 1009 1010 1011 1012

  if (tsAssert) {
    taosMsleep(300);
    abort();
  }

  return true;
}
1013
#endif