tlog.c 21.7 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 22 23 24 25 26 27
#include "ulog.h"

#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 已提交
28 29
#define MAX_LOGLINE_DUMP_CONTENT_SIZE (MAX_LOGLINE_DUMP_SIZE - 100)

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

D
fix bug  
dapan1121 已提交
33 34 35 36 37
#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 已提交
38

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

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

S
slguan 已提交
58
typedef struct {
L
Liu Jicong 已提交
59 60 61 62 63 64 65 66
  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 已提交
67 68 69
  pthread_mutex_t logMutex;
} SLogObj;

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

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

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

D
fix bug  
dapan1121 已提交
97
int64_t dbgEmptyW = 0;
D
fix bug  
dapan1121 已提交
98 99 100
int64_t dbgWN = 0;
int64_t dbgSmallWN = 0;
int64_t dbgBigWN = 0;
D
fix bug  
dapan1121 已提交
101 102
int64_t dbgWSize = 0;

L
Liu Jicong 已提交
103 104
static SLogObj   tsLogObj = {.fileNum = 1};
static void     *taosAsyncOutputLog(void *param);
S
slguan 已提交
105 106 107 108
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);
109
extern void      taosPrintCfg();
S
Shengliang Guan 已提交
110
static int32_t   taosCompressFile(char *srcFileName, char *destFileName);
S
slguan 已提交
111 112

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

S
Shengliang Guan 已提交
122 123 124 125
int32_t taosInitLog(const char *logName, int maxFiles) {
  char fullName[PATH_MAX] = {0};
  snprintf(fullName, PATH_MAX, "%s" TD_DIRSEP "%s", tsLogDir, logName);

S
slguan 已提交
126 127
  tsLogObj.logHandle = taosLogBuffNew(TSDB_DEFAULT_LOG_BUF_SIZE);
  if (tsLogObj.logHandle == NULL) return -1;
S
Shengliang Guan 已提交
128
  if (taosOpenLogFile(fullName, tsNumOfLogLines, maxFiles) < 0) return -1;
H
hzcheng 已提交
129 130 131 132
  if (taosStartLog() < 0) return -1;
  return 0;
}

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

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

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

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

  return false;
}

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

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

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

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

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

dengyihao's avatar
dengyihao 已提交
189
  taosRemoveOldFiles(tsLogDir, TABS(tsLogKeepDays));
S
TD-1263  
Shengliang Guan 已提交
190 191
}

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

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

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

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

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

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

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

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

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

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

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

  return 0;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return 0;
}

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

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

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

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

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

  if (len > MAX_LOGLINE_SIZE) len = MAX_LOGLINE_SIZE;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return tLogBuff;

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

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

D
fix bug  
dapan1121 已提交
565 566 567 568 569 570 571 572 573 574 575 576 577 578
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 已提交
579
static int32_t taosPushLogBuffer(SLogBuff *tLogBuff, char *msg, int32_t msgLen) {
L
Liu Jicong 已提交
580 581 582
  int32_t        start = 0;
  int32_t        end = 0;
  int32_t        remainSize = 0;
D
fix bug  
dapan1121 已提交
583
  static int64_t lostLine = 0;
L
Liu Jicong 已提交
584 585
  char           tmpBuf[40] = {0};
  int32_t        tmpBufLen = 0;
H
hzcheng 已提交
586 587 588 589 590 591 592

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

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

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

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

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

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

  pthread_mutex_unlock(&LOG_BUF_MUTEX(tLogBuff));

  return 0;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    if (tLogBuff->stop) break;
  }

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

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

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

734
  int32_t fd = taosOpenFileCreateWriteTrunc(destFileName);
S
Shengliang Guan 已提交
735 736 737 738 739
  if (fd < 0) {
    ret = -2;
    goto cmp_end;
  }

H
Haojun Liao 已提交
740 741 742 743 744 745 746 747 748 749 750
//  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);
//  }
S
Shengliang Guan 已提交
751 752 753 754 755

cmp_end:
  if (srcFp) {
    fclose(srcFp);
  }
H
Haojun Liao 已提交
756 757 758
//  if (dstFp) {
//    gzclose(dstFp);
//  }
S
Shengliang Guan 已提交
759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
  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);
}
S
Shengliang Guan 已提交
778

S
Shengliang Guan 已提交
779 780
void taosSetAllDebugFlag(int32_t flag) {
  if (!(flag & DEBUG_TRACE || flag & DEBUG_DEBUG || flag & DEBUG_DUMP)) return;
S
Shengliang Guan 已提交
781 782

  dDebugFlag = flag;
S
Shengliang Guan 已提交
783 784
  vDebugFlag = flag;
  mDebugFlag = flag;
S
Shengliang Guan 已提交
785
  cDebugFlag = flag;
S
Shengliang Guan 已提交
786 787 788 789 790 791 792 793 794 795 796
  jniDebugFlag = flag;
  uDebugFlag = flag;
  rpcDebugFlag = flag;
  qDebugFlag = flag;
  wDebugFlag = flag;
  sDebugFlag = flag;
  tsdbDebugFlag = flag;
  tqDebugFlag = flag;
  fsDebugFlag = flag;

  uInfo("all debug flag are set to %d", flag);
S
Shengliang Guan 已提交
797
}