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
S
slguan 已提交
17
#include "os.h"
S
Shengliang Guan 已提交
18
#include "ulog.h"
H
hzcheng 已提交
19
#include "tlog.h"
S
TD-2371  
Shengliang Guan 已提交
20
#include "tnote.h"
H
hzcheng 已提交
21
#include "tutil.h"
S
Shengliang Guan 已提交
22
#include "zlib.h"
S
Shengliang Guan 已提交
23
  
S
slguan 已提交
24 25 26 27 28 29 30
#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)
#define MAX_LOGLINE_DUMP_CONTENT_SIZE (MAX_LOGLINE_DUMP_SIZE - 100)

H
hzcheng 已提交
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 41 42 43 44 45
#define LOG_BUF_BUFFER(x) ((x)->buffer)
#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)

H
hzcheng 已提交
46 47
typedef struct {
  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 60 61 62 63 64 65 66 67 68 69 70
typedef struct {
  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;
  pthread_mutex_t logMutex;
} SLogObj;

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

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 96 97 98 99 100 101 102
// log
int32_t tsNumOfLogLines = 10000000;
int32_t mDebugFlag = 131;
int32_t sdbDebugFlag = 131;
int32_t dDebugFlag = 135;
int32_t vDebugFlag = 135;
int32_t cDebugFlag = 131;
int32_t jniDebugFlag = 131;
int32_t odbcDebugFlag = 131;
int32_t httpDebugFlag = 131;
int32_t mqttDebugFlag = 131;
int32_t monDebugFlag = 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;
int32_t cqDebugFlag = 131;
int32_t fsDebugFlag = 135;

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

S
slguan 已提交
109 110 111 112 113 114
static SLogObj   tsLogObj = { .fileNum = 1 };
static void *    taosAsyncOutputLog(void *param);
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);
S
TD-1263  
Shengliang Guan 已提交
115
extern void      taosPrintGlobalCfg();
S
Shengliang Guan 已提交
116
static int32_t   taosCompressFile(char *srcFileName, char *destFileName);
S
slguan 已提交
117 118

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

S
slguan 已提交
128 129 130 131
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 已提交
132 133 134 135
  if (taosStartLog() < 0) return -1;
  return 0;
}

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

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

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

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

  return false;
}

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

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

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

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

S
Shengliang Guan 已提交
183
  taosRenameFile(oldName, fileName);
S
TD-1574  
Shengliang Guan 已提交
184 185 186 187 188 189 190 191
  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 已提交
192
  taosRemoveOldFiles(tsLogDir, ABS(tsLogKeepDays));
S
TD-1263  
Shengliang Guan 已提交
193 194
}

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

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

S
Shengliang Guan 已提交
204
  taosUmaskFile(0);
H
hzcheng 已提交
205

206
  int32_t fd = taosOpenFileCreateWriteTrunc(name);
H
Hui Li 已提交
207
  if (fd < 0) {
208 209 210
    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 已提交
211 212
    return NULL;
  }
S
TD-1263  
Shengliang Guan 已提交
213

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

S
slguan 已提交
217 218 219 220
  int32_t oldFd = tsLogObj.logHandle->fd;
  tsLogObj.logHandle->fd = fd;
  tsLogObj.lines = 0;
  tsLogObj.openInProgress = 0;
S
TD-1263  
Shengliang Guan 已提交
221
  taosCloseLogByFd(oldFd);
S
TD-1263  
Shengliang Guan 已提交
222 223 224 225
  
  uInfo("   new log file:%d is opened", tsLogObj.flag);
  uInfo("==================================");
  taosPrintGlobalCfg();
S
TD-1263  
Shengliang Guan 已提交
226 227
  taosKeepOldLog(keepName);

H
hzcheng 已提交
228 229 230
  return NULL;
}

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

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

237
    uInfo("open new log file ......");
H
hzcheng 已提交
238 239 240 241 242 243 244 245 246
    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 已提交
247
  pthread_mutex_unlock(&tsLogObj.logMutex);
H
hzcheng 已提交
248 249 250 251

  return 0;
}

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

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

  taosOpenNewLogFile();
H
Hui Li 已提交
260
  (void)remove(lastName);
H
hzcheng 已提交
261

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

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

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

S
slguan 已提交
287 288 289
static void taosGetLogFileName(char *fn) {
  if (tsLogObj.fileNum > 1) {
    for (int32_t i = 0; i < tsLogObj.fileNum; i++) {
H
hzcheng 已提交
290 291 292 293 294 295 296 297 298
      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 已提交
299
        sprintf(tsLogObj.logName, "%s%d", fn, i);
H
hzcheng 已提交
300 301 302 303 304
        return;
      }
    }
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

  return 0;
}

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

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

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

402
  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 已提交
403
                ptm->tm_min, ptm->tm_sec, (int32_t)timeSecs.tv_usec, taosGetSelfPthreadId());
H
hzcheng 已提交
404 405 406
  len += sprintf(buffer + len, "%s", flags);

  va_start(argpointer, format);
S
slguan 已提交
407
  int32_t writeLen = vsnprintf(buffer + len, MAX_LOGLINE_CONTENT_SIZE, format, argpointer);
S
slguan 已提交
408
  if (writeLen <= 0) {
409
    char tmp[MAX_LOGLINE_DUMP_BUFFER_SIZE] = {0};
S
slguan 已提交
410 411 412 413 414 415 416 417
    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 已提交
418 419 420 421 422 423 424
  va_end(argpointer);

  if (len > MAX_LOGLINE_SIZE) len = MAX_LOGLINE_SIZE;

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

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

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

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

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

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

H
hzcheng 已提交
451
  char temp[256];
S
slguan 已提交
452
  int32_t  i, pos = 0, c = 0;
H
hzcheng 已提交
453 454 455 456 457 458 459

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

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

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

B
Bomin Zhang 已提交
471
void taosPrintLongString(const char *flags, int32_t dflag, const char *format, ...) {
S
slguan 已提交
472
  if (tsTotalLogDirGB != 0 && tsAvailLogDirGB < tsMinimalLogDirGB) {
S
slguan 已提交
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 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;
D
fix bug  
dapan1121 已提交
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 581 582 583
static int32_t taosPushLogBuffer(SLogBuff *tLogBuff, char *msg, int32_t msgLen) {
  int32_t start = 0;
  int32_t end = 0;
  int32_t remainSize = 0;
D
fix bug  
dapan1121 已提交
584 585 586
  static int64_t lostLine = 0;
  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) {
D
fix bug  
dapan1121 已提交
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

D
fix bug  
dapan1121 已提交
615 616
  //int32_t w = atomic_sub_fetch_32(&waitLock, 1);
  /*
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

  pthread_mutex_unlock(&LOG_BUF_MUTEX(tLogBuff));

D
fix bug  
dapan1121 已提交
627

H
hzcheng 已提交
628 629 630
  return 0;
}

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

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

D
fix bug  
dapan1121 已提交
637
static void taosWriteLog(SLogBuff *tLogBuff) {
D
fix bu  
dapan1121 已提交
638 639 640 641
  static int32_t lastDuration = 0;
  int32_t remainChecked = 0;
  int32_t start, end, pollSize;
  
D
fix bug  
dapan1121 已提交
642
  do {
D
fix bu  
dapan1121 已提交
643 644 645 646 647 648 649 650 651
    if (remainChecked == 0) {
      start = LOG_BUF_START(tLogBuff);
      end = LOG_BUF_END(tLogBuff);

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

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

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

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

S
Shengliang Guan 已提交
670
        taosWriteFile(tLogBuff->fd, LOG_BUF_BUFFER(tLogBuff), end);
H
hzcheng 已提交
671
    }
D
fix bug  
dapan1121 已提交
672 673

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

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

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

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

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

    remainChecked = 1;
D
fix bug  
dapan1121 已提交
703
  }while (1);
H
hzcheng 已提交
704 705
}

S
slguan 已提交
706
static void *taosAsyncOutputLog(void *param) {
H
hzcheng 已提交
707
  SLogBuff *tLogBuff = (SLogBuff *)param;
H
Haojun Liao 已提交
708
  setThreadName("log");
D
fix bug  
dapan1121 已提交
709
  
H
hzcheng 已提交
710
  while (1) {
D
fix bug  
dapan1121 已提交
711
    taosMsleep(writeInterval);
H
hzcheng 已提交
712 713

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

    if (tLogBuff->stop) break;
  }

  return NULL;
}
S
Shengliang Guan 已提交
721 722 723 724 725 726 727 728 729 730 731 732 733 734 735

int32_t taosCompressFile(char *srcFileName, char *destFileName) {
  int32_t compressSize = 163840;
  int32_t ret = 0;
  int32_t len = 0;
  char *  data = malloc(compressSize);
  FILE *  srcFp = NULL;
  gzFile  dstFp = NULL;

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

736
  int32_t fd = taosOpenFileCreateWriteTrunc(destFileName);
S
Shengliang Guan 已提交
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 779
  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);
}