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
// 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
dapan1121 已提交
102 103
int32_t ctgDebugFlag = 131;

S
Shengliang Guan 已提交
104

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

S
slguan 已提交
111 112 113 114 115 116
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);
117
extern void      taosPrintCfg();
S
Shengliang Guan 已提交
118
static int32_t   taosCompressFile(char *srcFileName, char *destFileName);
S
slguan 已提交
119 120

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

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

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

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

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

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

  return false;
}

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

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

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

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

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

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

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

S
Shengliang Guan 已提交
206
  taosUmaskFile(0);
H
hzcheng 已提交
207

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

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

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

H
hzcheng 已提交
230 231 232
  return NULL;
}

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

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

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

  return 0;
}

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

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

  taosOpenNewLogFile();
H
Hui Li 已提交
262
  (void)remove(lastName);
H
hzcheng 已提交
263

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return 0;
}

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

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

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

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

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

  if (len > MAX_LOGLINE_SIZE) len = MAX_LOGLINE_SIZE;

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

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

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

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

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

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

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

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

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

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

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

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

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

491
  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 已提交
492
                ptm->tm_min, ptm->tm_sec, (int32_t)timeSecs.tv_usec, taosGetSelfPthreadId());
H
hzcheng 已提交
493 494 495
  len += sprintf(buffer + len, "%s", flags);

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

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

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

S
slguan 已提交
504
  if ((dflag & DEBUG_FILE) && tsLogObj.logHandle && tsLogObj.logHandle->fd >= 0) {
505 506 507
    if (tsAsyncLog) {
      taosPushLogBuffer(tsLogObj.logHandle, buffer, len);
    } else {
S
Shengliang Guan 已提交
508
      taosWriteFile(tsLogObj.logHandle->fd, buffer, len);
509 510
    }
    
S
slguan 已提交
511 512
    if (tsLogObj.maxLines > 0) {
      atomic_add_fetch_32(&tsLogObj.lines, 1);
H
hzcheng 已提交
513

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

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

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

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

S
slguan 已提交
534
static SLogBuff *taosLogBuffNew(int32_t bufSize) {
H
hzcheng 已提交
535 536 537 538 539 540 541 542 543 544
  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 已提交
545
  tLogBuff->minBuffSize = bufSize / 10;
H
hzcheng 已提交
546 547 548
  tLogBuff->stop = 0;

  if (pthread_mutex_init(&LOG_BUF_MUTEX(tLogBuff), NULL) < 0) goto _err;
D
fix bug  
dapan1121 已提交
549
  //tsem_init(&(tLogBuff->buffNotEmpty), 0, 0);
H
hzcheng 已提交
550 551 552 553

  return tLogBuff;

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

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

D
fix bug  
dapan1121 已提交
568 569 570 571 572 573 574 575 576 577 578 579 580 581
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 已提交
582 583 584 585
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 已提交
586 587 588
  static int64_t lostLine = 0;
  char tmpBuf[40] = {0};
  int32_t tmpBufLen = 0;
H
hzcheng 已提交
589 590 591 592 593 594 595

  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 已提交
596
  remainSize = (start > end) ? (start - end - 1) : (start + LOG_BUF_SIZE(tLogBuff) - end - 1);
H
hzcheng 已提交
597

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

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

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

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

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

  pthread_mutex_unlock(&LOG_BUF_MUTEX(tLogBuff));

D
fix bug  
dapan1121 已提交
629

H
hzcheng 已提交
630 631 632
  return 0;
}

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

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

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

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

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

D
fix bu  
dapan1121 已提交
663 664 665 666
      lastDuration = 0;
    }

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

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

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

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

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

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

    writeInterval = MIN_LOG_INTERVAL;
D
fix bu  
dapan1121 已提交
703 704

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

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

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

    if (tLogBuff->stop) break;
  }

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

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;
  }

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