tlog.c 21.3 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
H
hzcheng 已提交
17
#include "tlog.h"
L
Liu Jicong 已提交
18
#include "os.h"
S
TD-2371  
Shengliang Guan 已提交
19
#include "tnote.h"
H
hzcheng 已提交
20
#include "tutil.h"
L
Liu Jicong 已提交
21
#include "ulog.h"
S
Shengliang Guan 已提交
22
#include "zlib.h"
L
Liu Jicong 已提交
23 24 25 26 27 28

#define MAX_LOGLINE_SIZE (1000)
#define MAX_LOGLINE_BUFFER_SIZE (MAX_LOGLINE_SIZE + 10)
#define MAX_LOGLINE_CONTENT_SIZE (MAX_LOGLINE_SIZE - 100)
#define MAX_LOGLINE_DUMP_SIZE (65 * 1024)
#define MAX_LOGLINE_DUMP_BUFFER_SIZE (MAX_LOGLINE_DUMP_SIZE + 10)
S
slguan 已提交
29 30
#define MAX_LOGLINE_DUMP_CONTENT_SIZE (MAX_LOGLINE_DUMP_SIZE - 100)

L
Liu Jicong 已提交
31
#define LOG_FILE_NAME_LEN 300
D
fix bug  
dapan1121 已提交
32
#define TSDB_DEFAULT_LOG_BUF_SIZE (20 * 1024 * 1024)  // 20MB
H
hzcheng 已提交
33

D
fix bug  
dapan1121 已提交
34 35 36 37 38
#define DEFAULT_LOG_INTERVAL 25
#define LOG_INTERVAL_STEP 5
#define MIN_LOG_INTERVAL 5
#define MAX_LOG_INTERVAL 25
#define LOG_MAX_WAIT_MSEC 1000
D
fix bug  
dapan1121 已提交
39

S
slguan 已提交
40
#define LOG_BUF_BUFFER(x) ((x)->buffer)
L
Liu Jicong 已提交
41 42 43 44
#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 已提交
45

H
hzcheng 已提交
46
typedef struct {
L
Liu Jicong 已提交
47
  char           *buffer;
S
slguan 已提交
48 49 50
  int32_t         buffStart;
  int32_t         buffEnd;
  int32_t         buffSize;
D
fix bu  
dapan1121 已提交
51
  int32_t         minBuffSize;
S
slguan 已提交
52 53
  int32_t         fd;
  int32_t         stop;
H
hzcheng 已提交
54 55
  pthread_t       asyncThread;
  pthread_mutex_t buffMutex;
S
slguan 已提交
56
  tsem_t          buffNotEmpty;
H
hzcheng 已提交
57 58
} SLogBuff;

S
slguan 已提交
59
typedef struct {
L
Liu Jicong 已提交
60 61 62 63 64 65 66 67
  int32_t         fileNum;
  int32_t         maxLines;
  int32_t         lines;
  int32_t         flag;
  int32_t         openInProgress;
  pid_t           pid;
  char            logName[LOG_FILE_NAME_LEN];
  SLogBuff       *logHandle;
S
slguan 已提交
68 69 70
  pthread_mutex_t logMutex;
} SLogObj;

L
Liu Jicong 已提交
71
int8_t tscEmbeddedInUtil = 0;
L
Liu Jicong 已提交
72

73
int32_t tsLogKeepDays = 0;
S
Shengliang Guan 已提交
74
int8_t  tsAsyncLog = 1;
S
slguan 已提交
75 76
float   tsTotalLogDirGB = 0;
float   tsAvailLogDirGB = 0;
S
Shengliang Guan 已提交
77
float   tsMinimalLogDirGB = 1.0f;
D
fix bug  
dapan1121 已提交
78
int64_t asyncLogLostLines = 0;
D
fix bug  
dapan1121 已提交
79
int32_t writeInterval = DEFAULT_LOG_INTERVAL;
D
fix bug  
dapan1121 已提交
80

S
Shengliang Guan 已提交
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
// log
int32_t tsNumOfLogLines = 10000000;
int32_t mDebugFlag = 131;
int32_t dDebugFlag = 135;
int32_t vDebugFlag = 135;
int32_t cDebugFlag = 131;
int32_t jniDebugFlag = 131;
int32_t odbcDebugFlag = 131;
int32_t qDebugFlag = 131;
int32_t rpcDebugFlag = 131;
int32_t uDebugFlag = 131;
int32_t debugFlag = 0;
int32_t sDebugFlag = 135;
int32_t wDebugFlag = 135;
int32_t tsdbDebugFlag = 131;
L
Liu Jicong 已提交
96
int32_t tqDebugFlag = 131;
S
Shengliang Guan 已提交
97 98
int32_t cqDebugFlag = 131;
int32_t fsDebugFlag = 135;
D
dapan1121 已提交
99 100
int32_t ctgDebugFlag = 131;

D
fix bug  
dapan1121 已提交
101
int64_t dbgEmptyW = 0;
D
fix bug  
dapan1121 已提交
102 103 104
int64_t dbgWN = 0;
int64_t dbgSmallWN = 0;
int64_t dbgBigWN = 0;
D
fix bug  
dapan1121 已提交
105 106
int64_t dbgWSize = 0;

L
Liu Jicong 已提交
107 108
static SLogObj   tsLogObj = {.fileNum = 1};
static void     *taosAsyncOutputLog(void *param);
S
slguan 已提交
109 110 111 112
static int32_t   taosPushLogBuffer(SLogBuff *tLogBuff, char *msg, int32_t msgLen);
static SLogBuff *taosLogBuffNew(int32_t bufSize);
static void      taosCloseLogByFd(int32_t oldFd);
static int32_t   taosOpenLogFile(char *fn, int32_t maxLines, int32_t maxFileNum);
113
extern void      taosPrintCfg();
S
Shengliang Guan 已提交
114
static int32_t   taosCompressFile(char *srcFileName, char *destFileName);
S
slguan 已提交
115 116

static int32_t taosStartLog() {
H
hzcheng 已提交
117 118
  pthread_attr_t threadAttr;
  pthread_attr_init(&threadAttr);
S
slguan 已提交
119
  if (pthread_create(&(tsLogObj.logHandle->asyncThread), &threadAttr, taosAsyncOutputLog, tsLogObj.logHandle) != 0) {
H
hzcheng 已提交
120 121 122 123 124 125
    return -1;
  }
  pthread_attr_destroy(&threadAttr);
  return 0;
}

S
slguan 已提交
126 127 128 129
int32_t taosInitLog(char *logName, int numOfLogLines, int maxFiles) {
  tsLogObj.logHandle = taosLogBuffNew(TSDB_DEFAULT_LOG_BUF_SIZE);
  if (tsLogObj.logHandle == NULL) return -1;
  if (taosOpenLogFile(logName, numOfLogLines, maxFiles) < 0) return -1;
H
hzcheng 已提交
130 131 132 133
  if (taosStartLog() < 0) return -1;
  return 0;
}

S
slguan 已提交
134 135 136 137
static void taosStopLog() {
  if (tsLogObj.logHandle) {
    tsLogObj.logHandle->stop = 1;
  }
H
hzcheng 已提交
138 139
}

S
slguan 已提交
140
void taosCloseLog() {
H
hzcheng 已提交
141
  taosStopLog();
L
Liu Jicong 已提交
142 143
  // tsem_post(&(tsLogObj.logHandle->buffNotEmpty));
  taosMsleep(MAX_LOG_INTERVAL / 1000);
S
slguan 已提交
144 145
  if (taosCheckPthreadValid(tsLogObj.logHandle->asyncThread)) {
    pthread_join(tsLogObj.logHandle->asyncThread, NULL);
S
slguan 已提交
146
  }
S
slguan 已提交
147 148 149
  // In case that other threads still use log resources causing invalid write in valgrind
  // we comment two lines below.
  // taosLogBuffDestroy(tsLogObj.logHandle);
H
hzcheng 已提交
150 151 152
  // taosCloseLog();
}

S
Shengliang Guan 已提交
153
static bool taosLockLogFile(int32_t fd) {
H
hzcheng 已提交
154 155
  if (fd < 0) return false;

S
slguan 已提交
156
  if (tsLogObj.fileNum > 1) {
157
    int32_t ret = taosLockFile(fd);
H
hzcheng 已提交
158 159 160 161 162 163 164 165
    if (ret == 0) {
      return true;
    }
  }

  return false;
}

S
Shengliang Guan 已提交
166
static void taosUnLockLogFile(int32_t fd) {
H
hzcheng 已提交
167 168
  if (fd < 0) return;

S
slguan 已提交
169
  if (tsLogObj.fileNum > 1) {
S
Shengliang Guan 已提交
170
    taosUnLockFile(fd);
H
hzcheng 已提交
171 172 173
  }
}

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

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

S
Shengliang Guan 已提交
181
  taosRenameFile(oldName, fileName);
S
TD-1574  
Shengliang Guan 已提交
182 183 184 185 186 187 188 189
  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) {
      (void)remove(fileName);
    }
  }

S
Shengliang Guan 已提交
190
  taosRemoveOldFiles(tsLogDir, ABS(tsLogKeepDays));
S
TD-1263  
Shengliang Guan 已提交
191 192
}

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

S
slguan 已提交
197 198
  tsLogObj.flag ^= 1;
  tsLogObj.lines = 0;
S
TD-1263  
Shengliang Guan 已提交
199
  char name[LOG_FILE_NAME_LEN + 20];
S
slguan 已提交
200
  sprintf(name, "%s.%d", tsLogObj.logName, tsLogObj.flag);
H
hzcheng 已提交
201

S
Shengliang Guan 已提交
202
  taosUmaskFile(0);
H
hzcheng 已提交
203

204
  int32_t fd = taosOpenFileCreateWriteTrunc(name);
H
Hui Li 已提交
205
  if (fd < 0) {
206 207 208
    tsLogObj.openInProgress = 0;
    tsLogObj.lines = tsLogObj.maxLines - 1000;
    uError("open new log file fail! fd:%d reason:%s, reuse lastlog", fd, strerror(errno));
H
Hui Li 已提交
209 210
    return NULL;
  }
S
TD-1263  
Shengliang Guan 已提交
211

S
Shengliang Guan 已提交
212 213
  taosLockLogFile(fd);
  (void)taosLSeekFile(fd, 0, SEEK_SET);
H
hzcheng 已提交
214

S
slguan 已提交
215 216 217 218
  int32_t oldFd = tsLogObj.logHandle->fd;
  tsLogObj.logHandle->fd = fd;
  tsLogObj.lines = 0;
  tsLogObj.openInProgress = 0;
S
TD-1263  
Shengliang Guan 已提交
219
  taosCloseLogByFd(oldFd);
L
Liu Jicong 已提交
220

S
TD-1263  
Shengliang Guan 已提交
221 222
  uInfo("   new log file:%d is opened", tsLogObj.flag);
  uInfo("==================================");
223
  taosPrintCfg();
S
TD-1263  
Shengliang Guan 已提交
224 225
  taosKeepOldLog(keepName);

H
hzcheng 已提交
226 227 228
  return NULL;
}

S
slguan 已提交
229 230
static int32_t taosOpenNewLogFile() {
  pthread_mutex_lock(&tsLogObj.logMutex);
H
hzcheng 已提交
231

S
slguan 已提交
232 233
  if (tsLogObj.lines > tsLogObj.maxLines && tsLogObj.openInProgress == 0) {
    tsLogObj.openInProgress = 1;
H
hzcheng 已提交
234

235
    uInfo("open new log file ......");
H
hzcheng 已提交
236 237 238 239 240 241 242 243 244
    pthread_t      thread;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    pthread_create(&thread, &attr, taosThreadToOpenNewFile, NULL);
    pthread_attr_destroy(&attr);
  }

S
slguan 已提交
245
  pthread_mutex_unlock(&tsLogObj.logMutex);
H
hzcheng 已提交
246 247 248 249

  return 0;
}

S
slguan 已提交
250 251 252
void taosResetLog() {
  char lastName[LOG_FILE_NAME_LEN + 20];
  sprintf(lastName, "%s.%d", tsLogObj.logName, tsLogObj.flag);
H
hzcheng 已提交
253 254

  // force create a new log file
S
slguan 已提交
255
  tsLogObj.lines = tsLogObj.maxLines + 10;
H
hzcheng 已提交
256 257

  taosOpenNewLogFile();
H
Hui Li 已提交
258
  (void)remove(lastName);
H
hzcheng 已提交
259

260 261
  uInfo("==================================");
  uInfo("   reset log file ");
H
hzcheng 已提交
262 263
}

S
slguan 已提交
264
static bool taosCheckFileIsOpen(char *logFileName) {
S
Shengliang Guan 已提交
265
  int32_t fd = taosOpenFileWrite(logFileName);
H
hzcheng 已提交
266
  if (fd < 0) {
267 268 269 270 271 272
    if (errno == ENOENT) {
      return false;
    } else {
      printf("\nfailed to open log file:%s, reason:%s\n", logFileName, strerror(errno));
      return true;
    }
H
hzcheng 已提交
273 274
  }

S
Shengliang Guan 已提交
275 276 277
  if (taosLockLogFile(fd)) {
    taosUnLockLogFile(fd);
    taosCloseFile(fd);
H
hzcheng 已提交
278 279
    return false;
  } else {
S
Shengliang Guan 已提交
280
    taosCloseFile(fd);
H
hzcheng 已提交
281 282 283 284
    return true;
  }
}

S
slguan 已提交
285 286 287
static void taosGetLogFileName(char *fn) {
  if (tsLogObj.fileNum > 1) {
    for (int32_t i = 0; i < tsLogObj.fileNum; i++) {
H
hzcheng 已提交
288 289 290 291 292 293 294 295 296
      char fileName[LOG_FILE_NAME_LEN];

      sprintf(fileName, "%s%d.0", fn, i);
      bool file1open = taosCheckFileIsOpen(fileName);

      sprintf(fileName, "%s%d.1", fn, i);
      bool file2open = taosCheckFileIsOpen(fileName);

      if (!file1open && !file2open) {
S
slguan 已提交
297
        sprintf(tsLogObj.logName, "%s%d", fn, i);
H
hzcheng 已提交
298 299 300 301 302
        return;
      }
    }
  }

H
Hui Li 已提交
303 304 305
  if (strlen(fn) < LOG_FILE_NAME_LEN) {
    strcpy(tsLogObj.logName, fn);
  }
H
hzcheng 已提交
306 307
}

S
slguan 已提交
308
static int32_t taosOpenLogFile(char *fn, int32_t maxLines, int32_t maxFileNum) {
S
slguan 已提交
309 310
#ifdef WINDOWS
  /*
L
Liu Jicong 已提交
311 312 313
   * always set maxFileNum to 1
   * means client log filename is unique in windows
   */
S
slguan 已提交
314 315 316
  maxFileNum = 1;
#endif

S
Shengliang Guan 已提交
317 318 319
  char    name[LOG_FILE_NAME_LEN + 50] = "\0";
  int32_t logstat0_mtime, logstat1_mtime;
  int32_t size;
H
hzcheng 已提交
320

S
slguan 已提交
321 322
  tsLogObj.maxLines = maxLines;
  tsLogObj.fileNum = maxFileNum;
H
hzcheng 已提交
323 324
  taosGetLogFileName(fn);

H
Hui Li 已提交
325 326 327 328
  if (strlen(fn) < LOG_FILE_NAME_LEN + 50 - 2) {
    strcpy(name, fn);
    strcat(name, ".0");
  }
S
Shengliang Guan 已提交
329
  bool log0Exist = taosStatFile(name, NULL, &logstat0_mtime) >= 0;
H
hzcheng 已提交
330

S
TD-1263  
Shengliang Guan 已提交
331 332 333 334
  if (strlen(fn) < LOG_FILE_NAME_LEN + 50 - 2) {
    strcpy(name, fn);
    strcat(name, ".1");
  }
S
Shengliang Guan 已提交
335 336
  bool log1Exist = taosStatFile(name, NULL, &logstat1_mtime) >= 0;

H
hzcheng 已提交
337
  // if none of the log files exist, open 0, if both exists, open the old one
S
TD-1263  
Shengliang Guan 已提交
338 339 340
  if (!log0Exist && !log1Exist) {
    tsLogObj.flag = 0;
  } else if (!log1Exist) {
S
slguan 已提交
341
    tsLogObj.flag = 0;
S
TD-1263  
Shengliang Guan 已提交
342 343
  } else if (!log0Exist) {
    tsLogObj.flag = 1;
H
hzcheng 已提交
344
  } else {
S
Shengliang Guan 已提交
345
    tsLogObj.flag = (logstat0_mtime > logstat1_mtime) ? 0 : 1;
H
hzcheng 已提交
346 347
  }

H
Hui Li 已提交
348 349
  char fileName[LOG_FILE_NAME_LEN + 50] = "\0";
  sprintf(fileName, "%s.%d", tsLogObj.logName, tsLogObj.flag);
S
slguan 已提交
350
  pthread_mutex_init(&tsLogObj.logMutex, NULL);
H
hzcheng 已提交
351

S
Shengliang Guan 已提交
352 353
  taosUmaskFile(0);
  tsLogObj.logHandle->fd = taosOpenFileCreateWrite(fileName);
H
hzcheng 已提交
354

S
slguan 已提交
355
  if (tsLogObj.logHandle->fd < 0) {
H
Hui Li 已提交
356
    printf("\nfailed to open log file:%s, reason:%s\n", fileName, strerror(errno));
H
hzcheng 已提交
357 358
    return -1;
  }
S
Shengliang Guan 已提交
359
  taosLockLogFile(tsLogObj.logHandle->fd);
H
hzcheng 已提交
360 361

  // only an estimate for number of lines
S
Shengliang Guan 已提交
362 363
  int64_t filesize = 0;
  if (taosFStatFile(tsLogObj.logHandle->fd, &filesize, NULL) < 0) {
H
Hui Li 已提交
364
    printf("\nfailed to fstat log file:%s, reason:%s\n", fileName, strerror(errno));
H
Hui Li 已提交
365 366
    return -1;
  }
S
Shengliang Guan 已提交
367
  size = (int32_t)filesize;
S
slguan 已提交
368
  tsLogObj.lines = size / 60;
H
hzcheng 已提交
369

S
Shengliang Guan 已提交
370
  taosLSeekFile(tsLogObj.logHandle->fd, 0, SEEK_END);
H
hzcheng 已提交
371 372

  sprintf(name, "==================================================\n");
S
Shengliang Guan 已提交
373
  taosWriteFile(tsLogObj.logHandle->fd, name, (uint32_t)strlen(name));
H
hzcheng 已提交
374
  sprintf(name, "                new log file                      \n");
S
Shengliang Guan 已提交
375
  taosWriteFile(tsLogObj.logHandle->fd, name, (uint32_t)strlen(name));
H
hzcheng 已提交
376
  sprintf(name, "==================================================\n");
S
Shengliang Guan 已提交
377
  taosWriteFile(tsLogObj.logHandle->fd, name, (uint32_t)strlen(name));
H
hzcheng 已提交
378 379 380 381

  return 0;
}

B
Bomin Zhang 已提交
382
void taosPrintLog(const char *flags, int32_t dflag, const char *format, ...) {
S
slguan 已提交
383
  if (tsTotalLogDirGB != 0 && tsAvailLogDirGB < tsMinimalLogDirGB) {
L
Liu Jicong 已提交
384 385
    printf("server disk:%s space remain %.3f GB, total %.1f GB, stop print log.\n", tsLogDir, tsAvailLogDirGB,
           tsTotalLogDirGB);
S
slguan 已提交
386 387
    fflush(stdout);
    return;
S
slguan 已提交
388 389
  }

H
hzcheng 已提交
390
  va_list        argpointer;
L
Liu Jicong 已提交
391
  char           buffer[MAX_LOGLINE_BUFFER_SIZE] = {0};
S
slguan 已提交
392
  int32_t        len;
H
hzcheng 已提交
393 394 395 396
  struct tm      Tm, *ptm;
  struct timeval timeSecs;
  time_t         curTime;

S
Shengliang Guan 已提交
397
  taosGetTimeOfDay(&timeSecs);
H
hzcheng 已提交
398 399
  curTime = timeSecs.tv_sec;
  ptm = localtime_r(&curTime, &Tm);
S
slguan 已提交
400

401
  len = sprintf(buffer, "%02d/%02d %02d:%02d:%02d.%06d %08" PRId64 " ", ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour,
S
TD-2616  
Shengliang Guan 已提交
402
                ptm->tm_min, ptm->tm_sec, (int32_t)timeSecs.tv_usec, taosGetSelfPthreadId());
H
hzcheng 已提交
403 404 405
  len += sprintf(buffer + len, "%s", flags);

  va_start(argpointer, format);
S
slguan 已提交
406
  int32_t writeLen = vsnprintf(buffer + len, MAX_LOGLINE_CONTENT_SIZE, format, argpointer);
S
slguan 已提交
407
  if (writeLen <= 0) {
408
    char tmp[MAX_LOGLINE_DUMP_BUFFER_SIZE] = {0};
S
slguan 已提交
409 410 411 412 413 414 415 416
    writeLen = vsnprintf(tmp, MAX_LOGLINE_DUMP_CONTENT_SIZE, format, argpointer);
    strncpy(buffer + len, tmp, MAX_LOGLINE_CONTENT_SIZE);
    len += MAX_LOGLINE_CONTENT_SIZE;
  } else if (writeLen >= MAX_LOGLINE_CONTENT_SIZE) {
    len += MAX_LOGLINE_CONTENT_SIZE;
  } else {
    len += writeLen;
  }
H
hzcheng 已提交
417 418 419 420 421 422 423
  va_end(argpointer);

  if (len > MAX_LOGLINE_SIZE) len = MAX_LOGLINE_SIZE;

  buffer[len++] = '\n';
  buffer[len] = 0;

S
slguan 已提交
424
  if ((dflag & DEBUG_FILE) && tsLogObj.logHandle && tsLogObj.logHandle->fd >= 0) {
H
hzcheng 已提交
425
    if (tsAsyncLog) {
S
slguan 已提交
426
      taosPushLogBuffer(tsLogObj.logHandle, buffer, len);
H
hzcheng 已提交
427
    } else {
S
Shengliang Guan 已提交
428
      taosWriteFile(tsLogObj.logHandle->fd, buffer, len);
H
hzcheng 已提交
429 430
    }

S
slguan 已提交
431 432
    if (tsLogObj.maxLines > 0) {
      atomic_add_fetch_32(&tsLogObj.lines, 1);
H
hzcheng 已提交
433

S
slguan 已提交
434
      if ((tsLogObj.lines > tsLogObj.maxLines) && (tsLogObj.openInProgress == 0)) taosOpenNewLogFile();
H
hzcheng 已提交
435 436 437
    }
  }

L
Liu Jicong 已提交
438
  if (dflag & DEBUG_SCREEN) taosWriteFile(1, buffer, (uint32_t)len);
S
TD-2371  
Shengliang Guan 已提交
439
  if (dflag == 255) nInfo(buffer, len);
H
hzcheng 已提交
440 441
}

S
slguan 已提交
442
void taosDumpData(unsigned char *msg, int32_t len) {
S
slguan 已提交
443
  if (tsTotalLogDirGB != 0 && tsAvailLogDirGB < tsMinimalLogDirGB) {
L
Liu Jicong 已提交
444 445
    printf("server disk:%s space remain %.3f GB, total %.1f GB, stop dump log.\n", tsLogDir, tsAvailLogDirGB,
           tsTotalLogDirGB);
S
slguan 已提交
446
    fflush(stdout);
S
slguan 已提交
447 448 449
    return;
  }

L
Liu Jicong 已提交
450 451
  char    temp[256];
  int32_t i, pos = 0, c = 0;
H
hzcheng 已提交
452 453 454 455 456 457 458

  for (i = 0; i < len; ++i) {
    sprintf(temp + pos, "%02x ", msg[i]);
    c++;
    pos += 3;
    if (c >= 16) {
      temp[pos++] = '\n';
S
Shengliang Guan 已提交
459
      taosWriteFile(tsLogObj.logHandle->fd, temp, (uint32_t)pos);
H
hzcheng 已提交
460 461 462 463 464 465 466
      c = 0;
      pos = 0;
    }
  }

  temp[pos++] = '\n';

S
Shengliang Guan 已提交
467
  taosWriteFile(tsLogObj.logHandle->fd, temp, (uint32_t)pos);
H
hzcheng 已提交
468 469
}

B
Bomin Zhang 已提交
470
void taosPrintLongString(const char *flags, int32_t dflag, const char *format, ...) {
S
slguan 已提交
471
  if (tsTotalLogDirGB != 0 && tsAvailLogDirGB < tsMinimalLogDirGB) {
L
Liu Jicong 已提交
472 473
    printf("server disk:%s space remain %.3f GB, total %.1f GB, stop write log.\n", tsLogDir, tsAvailLogDirGB,
           tsTotalLogDirGB);
S
slguan 已提交
474
    fflush(stdout);
S
slguan 已提交
475 476 477
    return;
  }

H
hzcheng 已提交
478
  va_list        argpointer;
S
slguan 已提交
479
  char           buffer[MAX_LOGLINE_DUMP_BUFFER_SIZE];
S
TD-1364  
Shengliang Guan 已提交
480
  int32_t        len;
H
hzcheng 已提交
481 482 483 484
  struct tm      Tm, *ptm;
  struct timeval timeSecs;
  time_t         curTime;

S
Shengliang Guan 已提交
485
  taosGetTimeOfDay(&timeSecs);
H
hzcheng 已提交
486 487
  curTime = timeSecs.tv_sec;
  ptm = localtime_r(&curTime, &Tm);
S
slguan 已提交
488

489
  len = sprintf(buffer, "%02d/%02d %02d:%02d:%02d.%06d %08" PRId64 " ", ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour,
S
TD-2616  
Shengliang Guan 已提交
490
                ptm->tm_min, ptm->tm_sec, (int32_t)timeSecs.tv_usec, taosGetSelfPthreadId());
H
hzcheng 已提交
491 492 493
  len += sprintf(buffer + len, "%s", flags);

  va_start(argpointer, format);
S
slguan 已提交
494
  len += vsnprintf(buffer + len, MAX_LOGLINE_DUMP_CONTENT_SIZE, format, argpointer);
H
hzcheng 已提交
495 496
  va_end(argpointer);

S
slguan 已提交
497
  if (len > MAX_LOGLINE_DUMP_SIZE) len = MAX_LOGLINE_DUMP_SIZE;
H
hzcheng 已提交
498 499 500 501

  buffer[len++] = '\n';
  buffer[len] = 0;

S
slguan 已提交
502
  if ((dflag & DEBUG_FILE) && tsLogObj.logHandle && tsLogObj.logHandle->fd >= 0) {
503 504 505
    if (tsAsyncLog) {
      taosPushLogBuffer(tsLogObj.logHandle, buffer, len);
    } else {
S
Shengliang Guan 已提交
506
      taosWriteFile(tsLogObj.logHandle->fd, buffer, len);
507
    }
L
Liu Jicong 已提交
508

S
slguan 已提交
509 510
    if (tsLogObj.maxLines > 0) {
      atomic_add_fetch_32(&tsLogObj.lines, 1);
H
hzcheng 已提交
511

S
slguan 已提交
512
      if ((tsLogObj.lines > tsLogObj.maxLines) && (tsLogObj.openInProgress == 0)) taosOpenNewLogFile();
H
hzcheng 已提交
513 514 515
    }
  }

S
Shengliang Guan 已提交
516
  if (dflag & DEBUG_SCREEN) taosWriteFile(1, buffer, (uint32_t)len);
H
hzcheng 已提交
517 518
}

S
slguan 已提交
519 520 521 522 523
#if 0
void taosCloseLog() { 
  taosCloseLogByFd(tsLogObj.logHandle->fd); 
}
#endif
H
hzcheng 已提交
524

S
slguan 已提交
525
static void taosCloseLogByFd(int32_t fd) {
H
hzcheng 已提交
526
  if (fd >= 0) {
S
Shengliang Guan 已提交
527 528
    taosUnLockLogFile(fd);
    taosCloseFile(fd);
H
hzcheng 已提交
529 530 531
  }
}

S
slguan 已提交
532
static SLogBuff *taosLogBuffNew(int32_t bufSize) {
H
hzcheng 已提交
533 534 535 536 537 538 539 540 541 542
  SLogBuff *tLogBuff = NULL;

  tLogBuff = calloc(1, sizeof(SLogBuff));
  if (tLogBuff == NULL) return NULL;

  LOG_BUF_BUFFER(tLogBuff) = malloc(bufSize);
  if (LOG_BUF_BUFFER(tLogBuff) == NULL) goto _err;

  LOG_BUF_START(tLogBuff) = LOG_BUF_END(tLogBuff) = 0;
  LOG_BUF_SIZE(tLogBuff) = bufSize;
D
fix bu  
dapan1121 已提交
543
  tLogBuff->minBuffSize = bufSize / 10;
H
hzcheng 已提交
544 545 546
  tLogBuff->stop = 0;

  if (pthread_mutex_init(&LOG_BUF_MUTEX(tLogBuff), NULL) < 0) goto _err;
L
Liu Jicong 已提交
547
  // tsem_init(&(tLogBuff->buffNotEmpty), 0, 0);
H
hzcheng 已提交
548 549 550 551

  return tLogBuff;

_err:
S
TD-1848  
Shengliang Guan 已提交
552 553
  tfree(LOG_BUF_BUFFER(tLogBuff));
  tfree(tLogBuff);
H
hzcheng 已提交
554 555 556
  return NULL;
}

S
slguan 已提交
557 558
#if 0
static void taosLogBuffDestroy(SLogBuff *tLogBuff) {
S
slguan 已提交
559
  tsem_destroy(&(tLogBuff->buffNotEmpty));
H
hzcheng 已提交
560 561
  pthread_mutex_destroy(&(tLogBuff->buffMutex));
  free(tLogBuff->buffer);
S
TD-1848  
Shengliang Guan 已提交
562
  tfree(tLogBuff);
H
hzcheng 已提交
563
}
S
slguan 已提交
564
#endif
H
hzcheng 已提交
565

D
fix bug  
dapan1121 已提交
566 567 568 569 570 571 572 573 574 575 576 577 578 579
static void taosCopyLogBuffer(SLogBuff *tLogBuff, int32_t start, int32_t end, char *msg, int32_t msgLen) {
  if (start > end) {
    memcpy(LOG_BUF_BUFFER(tLogBuff) + end, msg, msgLen);
  } else {
    if (LOG_BUF_SIZE(tLogBuff) - end < msgLen) {
      memcpy(LOG_BUF_BUFFER(tLogBuff) + end, msg, LOG_BUF_SIZE(tLogBuff) - end);
      memcpy(LOG_BUF_BUFFER(tLogBuff), msg + LOG_BUF_SIZE(tLogBuff) - end, msgLen - LOG_BUF_SIZE(tLogBuff) + end);
    } else {
      memcpy(LOG_BUF_BUFFER(tLogBuff) + end, msg, msgLen);
    }
  }
  LOG_BUF_END(tLogBuff) = (LOG_BUF_END(tLogBuff) + msgLen) % LOG_BUF_SIZE(tLogBuff);
}

S
slguan 已提交
580
static int32_t taosPushLogBuffer(SLogBuff *tLogBuff, char *msg, int32_t msgLen) {
L
Liu Jicong 已提交
581 582 583
  int32_t        start = 0;
  int32_t        end = 0;
  int32_t        remainSize = 0;
D
fix bug  
dapan1121 已提交
584
  static int64_t lostLine = 0;
L
Liu Jicong 已提交
585 586
  char           tmpBuf[40] = {0};
  int32_t        tmpBufLen = 0;
H
hzcheng 已提交
587 588 589 590 591 592 593

  if (tLogBuff == NULL || tLogBuff->stop) return -1;

  pthread_mutex_lock(&LOG_BUF_MUTEX(tLogBuff));
  start = LOG_BUF_START(tLogBuff);
  end = LOG_BUF_END(tLogBuff);

D
fix bug  
dapan1121 已提交
594
  remainSize = (start > end) ? (start - end - 1) : (start + LOG_BUF_SIZE(tLogBuff) - end - 1);
H
hzcheng 已提交
595

D
fix bug  
dapan1121 已提交
596
  if (lostLine > 0) {
L
Liu Jicong 已提交
597
    sprintf(tmpBuf, "...Lost %" PRId64 " lines here...\n", lostLine);
D
dapan1121 已提交
598
    tmpBufLen = (int32_t)strlen(tmpBuf);
D
fix bug  
dapan1121 已提交
599 600 601 602 603
  }

  if (remainSize <= msgLen || ((lostLine > 0) && (remainSize <= (msgLen + tmpBufLen)))) {
    lostLine++;
    asyncLogLostLines++;
H
hzcheng 已提交
604 605 606 607
    pthread_mutex_unlock(&LOG_BUF_MUTEX(tLogBuff));
    return -1;
  }

D
fix bug  
dapan1121 已提交
608 609 610
  if (lostLine > 0) {
    taosCopyLogBuffer(tLogBuff, start, end, tmpBuf, tmpBufLen);
    lostLine = 0;
H
hzcheng 已提交
611
  }
D
fix bug  
dapan1121 已提交
612 613

  taosCopyLogBuffer(tLogBuff, LOG_BUF_START(tLogBuff), LOG_BUF_END(tLogBuff), msg, msgLen);
H
hzcheng 已提交
614

L
Liu Jicong 已提交
615
  // int32_t w = atomic_sub_fetch_32(&waitLock, 1);
D
fix bug  
dapan1121 已提交
616
  /*
D
fix bug  
dapan1121 已提交
617 618
  if (w <= 0 || ((remainSize - msgLen - tmpBufLen) < (LOG_BUF_SIZE(tLogBuff) * 4 /5))) {
    tsem_post(&(tLogBuff->buffNotEmpty));
D
fix bug  
dapan1121 已提交
619 620 621
    dbgPostN++;
  } else {
    dbgNoPostN++;
D
fix bug  
dapan1121 已提交
622
  }
D
fix bug  
dapan1121 已提交
623
  */
H
hzcheng 已提交
624 625 626 627 628 629

  pthread_mutex_unlock(&LOG_BUF_MUTEX(tLogBuff));

  return 0;
}

D
fix bu  
dapan1121 已提交
630
static int32_t taosGetLogRemainSize(SLogBuff *tLogBuff, int32_t start, int32_t end) {
D
fix bug  
dapan1121 已提交
631
  int32_t rSize = end - start;
H
hzcheng 已提交
632

D
fix bug  
dapan1121 已提交
633 634
  return rSize >= 0 ? rSize : LOG_BUF_SIZE(tLogBuff) + rSize;
}
H
hzcheng 已提交
635

D
fix bug  
dapan1121 已提交
636
static void taosWriteLog(SLogBuff *tLogBuff) {
D
fix bu  
dapan1121 已提交
637
  static int32_t lastDuration = 0;
L
Liu Jicong 已提交
638 639 640
  int32_t        remainChecked = 0;
  int32_t        start, end, pollSize;

D
fix bug  
dapan1121 已提交
641
  do {
D
fix bu  
dapan1121 已提交
642 643 644 645 646 647 648 649 650
    if (remainChecked == 0) {
      start = LOG_BUF_START(tLogBuff);
      end = LOG_BUF_END(tLogBuff);

      if (start == end) {
        dbgEmptyW++;
        writeInterval = MAX_LOG_INTERVAL;
        return;
      }
H
hzcheng 已提交
651

D
fix bu  
dapan1121 已提交
652 653 654
      pollSize = taosGetLogRemainSize(tLogBuff, start, end);
      if (pollSize < tLogBuff->minBuffSize) {
        lastDuration += writeInterval;
D
fix bug  
dapan1121 已提交
655
        if (lastDuration < LOG_MAX_WAIT_MSEC) {
D
fix bu  
dapan1121 已提交
656 657 658
          break;
        }
      }
D
fix bug  
dapan1121 已提交
659

D
fix bu  
dapan1121 已提交
660 661 662 663
      lastDuration = 0;
    }

    if (start < end) {
S
Shengliang Guan 已提交
664
      taosWriteFile(tLogBuff->fd, LOG_BUF_BUFFER(tLogBuff) + start, pollSize);
H
hzcheng 已提交
665
    } else {
L
Liu Jicong 已提交
666 667
      int32_t tsize = LOG_BUF_SIZE(tLogBuff) - start;
      taosWriteFile(tLogBuff->fd, LOG_BUF_BUFFER(tLogBuff) + start, tsize);
D
fix bug  
dapan1121 已提交
668

L
Liu Jicong 已提交
669
      taosWriteFile(tLogBuff->fd, LOG_BUF_BUFFER(tLogBuff), end);
H
hzcheng 已提交
670
    }
D
fix bug  
dapan1121 已提交
671 672

    dbgWN++;
L
Liu Jicong 已提交
673 674
    dbgWSize += pollSize;

D
fix bu  
dapan1121 已提交
675
    if (pollSize < tLogBuff->minBuffSize) {
D
fix bug  
dapan1121 已提交
676 677 678 679
      dbgSmallWN++;
      if (writeInterval < MAX_LOG_INTERVAL) {
        writeInterval += LOG_INTERVAL_STEP;
      }
L
Liu Jicong 已提交
680
    } else if (pollSize > LOG_BUF_SIZE(tLogBuff) / 3) {
D
fix bug  
dapan1121 已提交
681 682
      dbgBigWN++;
      writeInterval = MIN_LOG_INTERVAL;
L
Liu Jicong 已提交
683
    } else if (pollSize > LOG_BUF_SIZE(tLogBuff) / 4) {
D
fix bug  
dapan1121 已提交
684 685 686
      if (writeInterval > MIN_LOG_INTERVAL) {
        writeInterval -= LOG_INTERVAL_STEP;
      }
D
fix bug  
dapan1121 已提交
687 688 689 690
    }

    LOG_BUF_START(tLogBuff) = (LOG_BUF_START(tLogBuff) + pollSize) % LOG_BUF_SIZE(tLogBuff);

D
fix bu  
dapan1121 已提交
691 692 693
    start = LOG_BUF_START(tLogBuff);
    end = LOG_BUF_END(tLogBuff);

D
fix bug  
dapan1121 已提交
694
    pollSize = taosGetLogRemainSize(tLogBuff, start, end);
D
fix bu  
dapan1121 已提交
695
    if (pollSize < tLogBuff->minBuffSize) {
D
fix bug  
dapan1121 已提交
696 697 698 699
      break;
    }

    writeInterval = MIN_LOG_INTERVAL;
D
fix bu  
dapan1121 已提交
700 701

    remainChecked = 1;
L
Liu Jicong 已提交
702
  } while (1);
H
hzcheng 已提交
703 704
}

S
slguan 已提交
705
static void *taosAsyncOutputLog(void *param) {
H
hzcheng 已提交
706
  SLogBuff *tLogBuff = (SLogBuff *)param;
H
Haojun Liao 已提交
707
  setThreadName("log");
L
Liu Jicong 已提交
708

H
hzcheng 已提交
709
  while (1) {
D
fix bug  
dapan1121 已提交
710
    taosMsleep(writeInterval);
H
hzcheng 已提交
711 712

    // Polling the buffer
D
fix bug  
dapan1121 已提交
713
    taosWriteLog(tLogBuff);
H
hzcheng 已提交
714 715 716 717 718 719

    if (tLogBuff->stop) break;
  }

  return NULL;
}
S
Shengliang Guan 已提交
720 721 722 723 724

int32_t taosCompressFile(char *srcFileName, char *destFileName) {
  int32_t compressSize = 163840;
  int32_t ret = 0;
  int32_t len = 0;
L
Liu Jicong 已提交
725 726
  char   *data = malloc(compressSize);
  FILE   *srcFp = NULL;
S
Shengliang Guan 已提交
727 728 729 730 731 732 733 734
  gzFile  dstFp = NULL;

  srcFp = fopen(srcFileName, "r");
  if (srcFp == NULL) {
    ret = -1;
    goto cmp_end;
  }

735
  int32_t fd = taosOpenFileCreateWriteTrunc(destFileName);
S
Shengliang Guan 已提交
736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778
  if (fd < 0) {
    ret = -2;
    goto cmp_end;
  }

  dstFp = gzdopen(fd, "wb6f");
  if (dstFp == NULL) {
    ret = -3;
    close(fd);
    goto cmp_end;
  }

  while (!feof(srcFp)) {
    len = (int32_t)fread(data, 1, compressSize, srcFp);
    (void)gzwrite(dstFp, data, len);
  }

cmp_end:
  if (srcFp) {
    fclose(srcFp);
  }
  if (dstFp) {
    gzclose(dstFp);
  }
  free(data);

  return ret;
}

void taosPrintOsInfo() {
  SysNameInfo info = taosGetSysNameInfo();

  uInfo(" os pageSize:            %" PRId64 "(KB)", tsPageSize);
  uInfo(" os openMax:             %" PRId64, tsOpenMax);
  uInfo(" os streamMax:           %" PRId64, tsStreamMax);
  uInfo(" os numOfCores:          %d", tsNumOfCores);
  uInfo(" os totalMemory:         %d(MB)", tsTotalMemoryMB);
  uInfo(" os sysname:             %s", info.sysname);
  uInfo(" os nodename:            %s", info.nodename);
  uInfo(" os release:             %s", info.release);
  uInfo(" os version:             %s", info.version);
  uInfo(" os machine:             %s", info.machine);
}