tnote.c 7.5 KB
Newer Older
S
slguan 已提交
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
TD-2371  
Shengliang Guan 已提交
16
#define _DEFAULT_SOURCE
S
Shengliang Guan 已提交
17
#include "os.h"
S
TD-2371  
Shengliang Guan 已提交
18 19
#include "tutil.h"
#include "tglobal.h"
L
lihui 已提交
20 21
#include "tnote.h"

S
TD-2371  
Shengliang Guan 已提交
22 23
SNoteObj tsHttpNote;
SNoteObj tsTscNote;
S
TD-2371  
Shengliang Guan 已提交
24
SNoteObj tsInfoNote;
L
lihui 已提交
25

S
TD-2371  
Shengliang Guan 已提交
26 27
static int32_t taosOpenNoteWithMaxLines(char *fn, int32_t maxLines, int32_t maxNoteNum, SNoteObj *pNote);
static void    taosCloseNoteByFd(int32_t oldFd, SNoteObj *pNote);
L
lihui 已提交
28

S
TD-2371  
Shengliang Guan 已提交
29
static void taosInitNote(int32_t numOfLines, int32_t maxNotes, SNoteObj *pNote, char *name) {
S
TD-2371  
Shengliang Guan 已提交
30 31 32
  memset(pNote, 0, sizeof(SNoteObj));
  pNote->fileNum = 1;
  pNote->fd = -1;
L
lihui 已提交
33

S
TD-2371  
Shengliang Guan 已提交
34 35 36
  if (taosOpenNoteWithMaxLines(name, numOfLines, maxNotes, pNote) < 0) {
    fprintf(stderr, "failed to init note file\n");
  }
L
lihui 已提交
37

S
TD-2371  
Shengliang Guan 已提交
38 39 40 41
  taosNotePrint(pNote, "==================================================");
  taosNotePrint(pNote, "===================  new note  ===================");
  taosNotePrint(pNote, "==================================================");
}
L
lihui 已提交
42

S
TD-2371  
Shengliang Guan 已提交
43 44
void taosInitNotes() {
  char name[TSDB_FILENAME_LEN * 2] = {0};
S
slguan 已提交
45

S
TD-2371  
Shengliang Guan 已提交
46 47 48 49 50 51 52 53 54 55
  if (tsTscEnableRecordSql) {
    snprintf(name, TSDB_FILENAME_LEN * 2, "%s/tscsql-%d", tsLogDir, taosGetPId());
    taosInitNote(tsNumOfLogLines, 1, &tsTscNote, name);
  }

  if (tsHttpEnableRecordSql) {
    snprintf(name, TSDB_FILENAME_LEN * 2, "%s/httpsql", tsLogDir);
    taosInitNote(tsNumOfLogLines, 1, &tsHttpNote, name);
  }

S
TD-2371  
Shengliang Guan 已提交
56
  if (tscEmbedded == 1) {
S
TD-2371  
Shengliang Guan 已提交
57 58
    snprintf(name, TSDB_FILENAME_LEN * 2, "%s/taosinfo", tsLogDir);
    taosInitNote(tsNumOfLogLines, 1, &tsInfoNote, name);
S
TD-2371  
Shengliang Guan 已提交
59
  }
S
slguan 已提交
60 61
}

S
TD-2371  
Shengliang Guan 已提交
62
static bool taosLockNote(int32_t fd, SNoteObj *pNote) {
S
TD-2371  
Shengliang Guan 已提交
63
  if (fd < 0) return false;
S
slguan 已提交
64

S
TD-2371  
Shengliang Guan 已提交
65 66 67 68
  if (pNote->fileNum > 1) {
    int32_t ret = (int32_t)(flock(fd, LOCK_EX | LOCK_NB));
    if (ret == 0) {
      return true;
S
slguan 已提交
69
    }
S
TD-2371  
Shengliang Guan 已提交
70
  }
S
slguan 已提交
71

S
TD-2371  
Shengliang Guan 已提交
72
  return false;
S
slguan 已提交
73 74
}

S
TD-2371  
Shengliang Guan 已提交
75
static void taosUnLockNote(int32_t fd, SNoteObj *pNote) {
S
TD-2371  
Shengliang Guan 已提交
76
  if (fd < 0) return;
S
slguan 已提交
77

S
TD-2371  
Shengliang Guan 已提交
78 79 80
  if (pNote->fileNum > 1) {
    flock(fd, LOCK_UN | LOCK_NB);
  }
S
slguan 已提交
81 82
}

S
TD-2371  
Shengliang Guan 已提交
83
static void *taosThreadToOpenNewNote(void *param) {
S
TD-2371  
Shengliang Guan 已提交
84 85
  char      name[NOTE_FILE_NAME_LEN * 2];
  SNoteObj *pNote = (SNoteObj *)param;
S
slguan 已提交
86

87 88
  setThreadName("openNewNote");

S
TD-2371  
Shengliang Guan 已提交
89 90 91
  pNote->flag ^= 1;
  pNote->lines = 0;
  sprintf(name, "%s.%d", pNote->name, pNote->flag);
S
slguan 已提交
92

S
TD-2371  
Shengliang Guan 已提交
93
  umask(0);
S
slguan 已提交
94

S
TD-2371  
Shengliang Guan 已提交
95 96 97 98
  int32_t fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
  if (fd < 0) {
    return NULL;
  }
99

S
TD-2371  
Shengliang Guan 已提交
100 101
  taosLockNote(fd, pNote);
  (void)lseek(fd, 0, SEEK_SET);
S
slguan 已提交
102

S
TD-2371  
Shengliang Guan 已提交
103 104 105 106 107
  int32_t oldFd = pNote->fd;
  pNote->fd = fd;
  pNote->lines = 0;
  pNote->openInProgress = 0;
  taosNotePrint(pNote, "===============  new note is opened  =============");
S
slguan 已提交
108

S
TD-2371  
Shengliang Guan 已提交
109 110
  taosCloseNoteByFd(oldFd, pNote);
  return NULL;
S
slguan 已提交
111 112
}

S
TD-2371  
Shengliang Guan 已提交
113
static int32_t taosOpenNewNote(SNoteObj *pNote) {
S
TD-2371  
Shengliang Guan 已提交
114
  pthread_mutex_lock(&pNote->mutex);
S
slguan 已提交
115

S
TD-2371  
Shengliang Guan 已提交
116 117
  if (pNote->lines > pNote->maxLines && pNote->openInProgress == 0) {
    pNote->openInProgress = 1;
S
slguan 已提交
118

S
TD-2371  
Shengliang Guan 已提交
119 120 121 122 123
    taosNotePrint(pNote, "===============  open new note  ==================");
    pthread_t      pattern;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
S
slguan 已提交
124

S
TD-2371  
Shengliang Guan 已提交
125 126 127
    pthread_create(&pattern, &attr, taosThreadToOpenNewNote, (void *)pNote);
    pthread_attr_destroy(&attr);
  }
S
slguan 已提交
128

S
TD-2371  
Shengliang Guan 已提交
129
  pthread_mutex_unlock(&pNote->mutex);
S
slguan 已提交
130

S
TD-2371  
Shengliang Guan 已提交
131
  return pNote->fd;
S
slguan 已提交
132 133
}

S
TD-2371  
Shengliang Guan 已提交
134
static bool taosCheckNoteIsOpen(char *noteName, SNoteObj *pNote) {
S
TD-2371  
Shengliang Guan 已提交
135 136 137 138 139
  int32_t fd = open(noteName, O_WRONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
  if (fd < 0) {
    fprintf(stderr, "failed to open note:%s reason:%s\n", noteName, strerror(errno));
    return true;
  }
S
slguan 已提交
140

S
TD-2371  
Shengliang Guan 已提交
141 142 143 144 145 146 147 148
  if (taosLockNote(fd, pNote)) {
    taosUnLockNote(fd, pNote);
    close(fd);
    return false;
  } else {
    close(fd);
    return true;
  }
S
slguan 已提交
149 150
}

S
TD-2371  
Shengliang Guan 已提交
151
static void taosGetNoteName(char *fn, SNoteObj *pNote) {
S
TD-2371  
Shengliang Guan 已提交
152 153 154
  if (pNote->fileNum > 1) {
    for (int32_t i = 0; i < pNote->fileNum; i++) {
      char fileName[NOTE_FILE_NAME_LEN];
S
slguan 已提交
155

S
TD-2371  
Shengliang Guan 已提交
156 157
      sprintf(fileName, "%s%d.0", fn, i);
      bool file1open = taosCheckNoteIsOpen(fileName, pNote);
S
slguan 已提交
158

S
TD-2371  
Shengliang Guan 已提交
159 160
      sprintf(fileName, "%s%d.1", fn, i);
      bool file2open = taosCheckNoteIsOpen(fileName, pNote);
S
slguan 已提交
161

S
TD-2371  
Shengliang Guan 已提交
162 163 164 165
      if (!file1open && !file2open) {
        sprintf(pNote->name, "%s%d", fn, i);
        return;
      }
S
slguan 已提交
166
    }
S
TD-2371  
Shengliang Guan 已提交
167
  }
S
slguan 已提交
168

S
TD-2371  
Shengliang Guan 已提交
169 170 171
  if (strlen(fn) < NOTE_FILE_NAME_LEN) {
    strcpy(pNote->name, fn);
  }
S
slguan 已提交
172 173
}

S
TD-2371  
Shengliang Guan 已提交
174
static int32_t taosOpenNoteWithMaxLines(char *fn, int32_t maxLines, int32_t maxNoteNum, SNoteObj *pNote) {
S
TD-2371  
Shengliang Guan 已提交
175
  char    name[NOTE_FILE_NAME_LEN * 2] = {0};
S
TD-2371  
Shengliang Guan 已提交
176
  int32_t size;
S
TD-2371  
Shengliang Guan 已提交
177
  struct stat logstat0, logstat1;
S
slguan 已提交
178

S
TD-2371  
Shengliang Guan 已提交
179 180 181
  pNote->maxLines = maxLines;
  pNote->fileNum = maxNoteNum;
  taosGetNoteName(fn, pNote);
S
slguan 已提交
182

S
TD-2371  
Shengliang Guan 已提交
183 184 185
  if (strlen(fn) < NOTE_FILE_NAME_LEN + 50 - 2) {
    strcpy(name, fn);
    strcat(name, ".0");
S
TD-2371  
Shengliang Guan 已提交
186
  }
S
TD-2371  
Shengliang Guan 已提交
187
  bool log0Exist = stat(name, &logstat0) >= 0;
H
Hui Li 已提交
188

S
TD-2371  
Shengliang Guan 已提交
189 190 191 192 193
  if (strlen(fn) < NOTE_FILE_NAME_LEN + 50 - 2) {
    strcpy(name, fn);
    strcat(name, ".1");
  }
  bool log1Exist = stat(name, &logstat1) >= 0;
S
slguan 已提交
194

S
TD-2371  
Shengliang Guan 已提交
195
  if (!log0Exist && !log1Exist) {
S
TD-2371  
Shengliang Guan 已提交
196
    pNote->flag = 0;
S
TD-2371  
Shengliang Guan 已提交
197 198 199 200
  } else if (!log1Exist) {
    pNote->flag = 0;
  } else if (!log0Exist) {
    pNote->flag = 1;
S
TD-2371  
Shengliang Guan 已提交
201
  } else {
S
TD-2371  
Shengliang Guan 已提交
202
    pNote->flag = (logstat0.st_mtime > logstat1.st_mtime) ? 0 : 1;
S
TD-2371  
Shengliang Guan 已提交
203
  }
S
slguan 已提交
204

S
TD-2371  
Shengliang Guan 已提交
205
  char noteName[NOTE_FILE_NAME_LEN * 2] = {0};
S
TD-2371  
Shengliang Guan 已提交
206 207
  sprintf(noteName, "%s.%d", pNote->name, pNote->flag);
  pthread_mutex_init(&pNote->mutex, NULL);
S
slguan 已提交
208

S
TD-2371  
Shengliang Guan 已提交
209 210
  umask(0);
  pNote->fd = open(noteName, O_WRONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
S
slguan 已提交
211

S
TD-2371  
Shengliang Guan 已提交
212 213 214 215 216
  if (pNote->fd < 0) {
    fprintf(stderr, "failed to open note file:%s reason:%s\n", noteName, strerror(errno));
    return -1;
  }
  taosLockNote(pNote->fd, pNote);
S
slguan 已提交
217

S
TD-2371  
Shengliang Guan 已提交
218 219 220 221 222 223 224 225
  // only an estimate for number of lines
  struct stat filestat;
  if (fstat(pNote->fd, &filestat) < 0) {
    fprintf(stderr, "failed to fstat note file:%s reason:%s\n", noteName, strerror(errno));
    return -1;
  }
  size = (int32_t)filestat.st_size;
  pNote->lines = size / 60;
S
slguan 已提交
226

S
TD-2371  
Shengliang Guan 已提交
227
  lseek(pNote->fd, 0, SEEK_END);
S
slguan 已提交
228

S
TD-2371  
Shengliang Guan 已提交
229
  return 0;
S
slguan 已提交
230 231
}

S
TD-2371  
Shengliang Guan 已提交
232
void taosNotePrintBuffer(SNoteObj *pNote, char *buffer, int32_t len) {
S
TD-2371  
Shengliang Guan 已提交
233
  if (pNote->fd <= 0) return;
S
TD-2371  
Shengliang Guan 已提交
234 235 236 237 238 239 240 241
  taosWrite(pNote->fd, buffer, len);

  if (pNote->maxLines > 0) {
    pNote->lines++;
    if ((pNote->lines > pNote->maxLines) && (pNote->openInProgress == 0)) taosOpenNewNote(pNote);
  }
}

S
TD-2371  
Shengliang Guan 已提交
242 243 244 245 246 247 248 249 250 251 252
void taosNotePrint(SNoteObj *pNote, const char *const format, ...) {
  va_list        argpointer;
  char           buffer[MAX_NOTE_LINE_SIZE + 2];
  int32_t        len;
  struct tm      Tm, *ptm;
  struct timeval timeSecs;
  time_t         curTime;

  gettimeofday(&timeSecs, NULL);
  curTime = timeSecs.tv_sec;
  ptm = localtime_r(&curTime, &Tm);
253
  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 已提交
254
                ptm->tm_min, ptm->tm_sec, (int32_t)timeSecs.tv_usec, taosGetSelfPthreadId());
S
TD-2371  
Shengliang Guan 已提交
255 256 257 258 259 260 261 262 263
  va_start(argpointer, format);
  len += vsnprintf(buffer + len, MAX_NOTE_LINE_SIZE - len, format, argpointer);
  va_end(argpointer);

  if (len >= MAX_NOTE_LINE_SIZE) len = MAX_NOTE_LINE_SIZE - 2;

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

S
TD-2371  
Shengliang Guan 已提交
264
  taosNotePrintBuffer(pNote, buffer, len);
S
slguan 已提交
265 266
}

S
TD-2371  
Shengliang Guan 已提交
267
// static void taosCloseNote(SNoteObj *pNote) { taosCloseNoteByFd(pNote->fd, pNote); }
S
slguan 已提交
268

S
TD-2371  
Shengliang Guan 已提交
269
static void taosCloseNoteByFd(int32_t fd, SNoteObj *pNote) {
S
TD-2371  
Shengliang Guan 已提交
270 271 272 273
  if (fd >= 0) {
    taosUnLockNote(fd, pNote);
    close(fd);
  }
S
slguan 已提交
274
}