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
#include "tutil.h"
19
#include "tdef.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

46
#if 0
S
TD-2371  
Shengliang Guan 已提交
47 48 49 50 51 52 53 54 55 56
  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 已提交
57
  if (tscEmbedded == 1) {
S
TD-2371  
Shengliang Guan 已提交
58 59
    snprintf(name, TSDB_FILENAME_LEN * 2, "%s/taosinfo", tsLogDir);
    taosInitNote(tsNumOfLogLines, 1, &tsInfoNote, name);
S
TD-2371  
Shengliang Guan 已提交
60
  }
61
#endif  
S
slguan 已提交
62 63
}

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

S
TD-2371  
Shengliang Guan 已提交
67
  if (pNote->fileNum > 1) {
68
    int32_t ret = (int32_t)taosLockFile(fd);
S
TD-2371  
Shengliang Guan 已提交
69 70
    if (ret == 0) {
      return true;
S
slguan 已提交
71
    }
S
TD-2371  
Shengliang Guan 已提交
72
  }
S
slguan 已提交
73

S
TD-2371  
Shengliang Guan 已提交
74
  return false;
S
slguan 已提交
75 76
}

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

S
TD-2371  
Shengliang Guan 已提交
80
  if (pNote->fileNum > 1) {
81
    taosUnLockFile(fd);
S
TD-2371  
Shengliang Guan 已提交
82
  }
S
slguan 已提交
83 84
}

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

89 90
  setThreadName("openNewNote");

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

95
  taosUmaskFile(0);
S
slguan 已提交
96

97
  int32_t fd = taosOpenFileCreateWriteTrunc(name);
S
TD-2371  
Shengliang Guan 已提交
98 99 100
  if (fd < 0) {
    return NULL;
  }
101

S
TD-2371  
Shengliang Guan 已提交
102
  taosLockNote(fd, pNote);
S
Shengliang Guan 已提交
103
  (void)taosLSeekFile(fd, 0, SEEK_SET);
S
slguan 已提交
104

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

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

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

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

S
TD-2371  
Shengliang Guan 已提交
121 122 123 124 125
    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 已提交
126

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

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

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

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

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

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

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

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

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

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

S
TD-2371  
Shengliang Guan 已提交
176
static int32_t taosOpenNoteWithMaxLines(char *fn, int32_t maxLines, int32_t maxNoteNum, SNoteObj *pNote) {
S
TD-2371  
Shengliang Guan 已提交
177
  char    name[NOTE_FILE_NAME_LEN * 2] = {0};
S
TD-2371  
Shengliang Guan 已提交
178
  int32_t size;
179
  int32_t logstat0_mtime, logstat1_mtime;
S
slguan 已提交
180

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

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

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

S
TD-2371  
Shengliang Guan 已提交
197
  if (!log0Exist && !log1Exist) {
S
TD-2371  
Shengliang Guan 已提交
198
    pNote->flag = 0;
S
TD-2371  
Shengliang Guan 已提交
199 200 201 202
  } else if (!log1Exist) {
    pNote->flag = 0;
  } else if (!log0Exist) {
    pNote->flag = 1;
S
TD-2371  
Shengliang Guan 已提交
203
  } else {
204
    pNote->flag = (logstat0_mtime > logstat1_mtime) ? 0 : 1;
S
TD-2371  
Shengliang Guan 已提交
205
  }
S
slguan 已提交
206

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

211 212
  taosUmaskFile(0);
  pNote->fd = taosOpenFileCreateWrite(noteName);
S
slguan 已提交
213

S
TD-2371  
Shengliang Guan 已提交
214 215 216 217 218
  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 已提交
219

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

S
Shengliang Guan 已提交
229
  taosLSeekFile(pNote->fd, 0, SEEK_END);
S
slguan 已提交
230

S
TD-2371  
Shengliang Guan 已提交
231
  return 0;
S
slguan 已提交
232 233
}

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

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

S
TD-2371  
Shengliang Guan 已提交
244 245 246 247 248 249 250 251
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;

252
  taosGetTimeOfDay(&timeSecs);
S
TD-2371  
Shengliang Guan 已提交
253 254
  curTime = timeSecs.tv_sec;
  ptm = localtime_r(&curTime, &Tm);
255
  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 已提交
256
                ptm->tm_min, ptm->tm_sec, (int32_t)timeSecs.tv_usec, taosGetSelfPthreadId());
S
TD-2371  
Shengliang Guan 已提交
257 258 259 260 261 262 263 264 265
  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 已提交
266
  taosNotePrintBuffer(pNote, buffer, len);
S
slguan 已提交
267 268
}

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

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