00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 #include "jsoc_main.h"
00068 #include <regex.h>
00069 #include <dirent.h>
00070
00071 char *module_name = "accessreplogs";
00072
00073 typedef enum
00074 {
00075 kARLErr_Success = 0,
00076 kARLErr_MissingSU,
00077 kARLErr_Argument,
00078 kARLErr_LogFileSeries,
00079 kARLErr_FileIO,
00080 kARLErr_InvalidLog,
00081 kARLErr_InvalidRange
00082 } ARLError_t;
00083
00084
00085 #define kLogs "logs"
00086 #define kPath "path"
00087 #define kAction "action"
00088 #define kLFRegEx "regexp"
00089 #define kBegin "beg"
00090 #define kEnd "end"
00091
00092 #define kActionRetrieve "ret"
00093 #define kActionStore "str"
00094
00095 #define kDefRegexp "slogs_([0-9]+)-([0-9]+)[.]tar[.]gz"
00096
00097
00098
00099 #define kObsDate "obsdate"
00100 #define kCBegin "cbegin"
00101 #define kCEnd "cend"
00102
00103
00104 ModuleArgs_t module_args[] =
00105 {
00106 {ARG_STRING,
00107 kLogs,
00108 NULL,
00109 "Dataseries containing the slony log files",
00110 NULL},
00111
00112 {ARG_STRING,
00113 kPath,
00114 NULL,
00115 "Path of log files or a single log file to ingest, or of location to copy logs to",
00116 NULL},
00117
00118 {ARG_STRING,
00119 kAction,
00120 NULL,
00121 "Store, retrieve, delete, etc. sql logs from SUMS",
00122 NULL},
00123
00124 {ARG_STRING,
00125 kLFRegEx,
00126 kDefRegexp,
00127 "POSIX regular expression that matches the log-file file names",
00128 NULL},
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 {ARG_END}
00151 };
00152
00153 static ARLError_t GetLogPaths(DRMS_RecordSet_t *rs, char ***paths)
00154 {
00155 ARLError_t err = kARLErr_Success;
00156 int irec;
00157 DRMS_Record_t *rec = NULL;
00158 DRMS_Segment_t *seg = NULL;
00159 char filepath[DRMS_MAXPATHLEN];
00160
00161 if (rs && rs->n > 0 && paths)
00162 {
00163 *paths = (char **)malloc(sizeof(char *) * rs->n);
00164
00165
00166 if (drms_stage_records(rs, 1, 0) != DRMS_SUCCESS)
00167 {
00168 err = kARLErr_MissingSU;
00169 }
00170
00171 for (irec = 0; irec < rs->n; irec++)
00172 {
00173 rec = rs->records[irec];
00174 seg = drms_segment_lookupnum(rec, 0);
00175
00176 if (seg)
00177 {
00178 drms_segment_filename(seg, filepath);
00179
00180 if (strlen(filepath))
00181 {
00182 (*paths)[irec] = strdup(filepath);
00183 }
00184 else
00185 {
00186 (*paths)[irec] = NULL;
00187 }
00188 }
00189 else
00190 {
00191
00192 fprintf(stderr, "Expected segment not found.\n");
00193 err = kARLErr_LogFileSeries;
00194 break;
00195 }
00196 }
00197 }
00198 else
00199 {
00200 fprintf(stderr, "Invalid arguments to GetLogPaths().\n");
00201 err = kARLErr_Argument;
00202 }
00203
00204 return err;
00205 }
00206
00207 DRMS_RecordSet_t *RetrieveRecords(const char *logs, int64_t beg, int64_t end, ARLError_t *err)
00208 {
00209 DRMS_RecordSet_t *rs = NULL;
00210 int status = DRMS_SUCCESS;
00211
00212 char query[DRMS_MAXQUERYLEN];
00213
00214 snprintf(query,
00215 sizeof(query),
00216 "%s[? (%s <= %lld AND %s >= %lld) OR (%s > %lld AND %s < %lld) OR (%s <= %lld AND %s >= %lld) ?]",
00217 logs,
00218 kCBegin, (long long)beg, kCEnd, (long long)beg,
00219 kCBegin, (long long)beg, kCEnd, (long long)end,
00220 kCBegin, (long long)end, kCEnd, (long long)end);
00221
00222 rs = drms_open_records(drms_env, query, &status);
00223
00224 if (status || !rs || rs->n == 0)
00225 {
00226 if (err)
00227 {
00228 *err = kARLErr_InvalidRange;
00229 }
00230 }
00231
00232 return rs;
00233 }
00234
00235 ARLError_t IngestFile(const char *path, const char *basefile, DRMS_Record_t *orec, regex_t *regexp)
00236 {
00237 ARLError_t err = kARLErr_InvalidLog;
00238
00239 char dirEntry[PATH_MAX] = {0};
00240 regmatch_t matches[3];
00241 char *bcountertxt = NULL;
00242 char *ecountertxt = NULL;
00243 long long bcounter;
00244 long long ecounter;
00245 DRMS_Segment_t *seg = NULL;
00246 int indx;
00247 char *filetmp = NULL;
00248 struct stat stBuf;
00249 DRMS_RecordSet_t *rs = NULL;
00250 int ioerr = 0;
00251
00252 filetmp = strdup(basefile);
00253
00254
00255 if (regexec(regexp, filetmp, 3, matches, 0) == 0)
00256 {
00257
00258 filetmp[matches[1].rm_eo] = '\0';
00259 indx = matches[1].rm_so;
00260 bcountertxt = strdup(filetmp + indx);
00261 sscanf(bcountertxt, "%lld", &bcounter);
00262
00263
00264 filetmp[matches[2].rm_eo] = '\0';
00265 indx = matches[2].rm_so;
00266 ecountertxt = strdup(filetmp + indx);
00267 sscanf(ecountertxt, "%lld", &ecounter);
00268
00269 snprintf(dirEntry,
00270 sizeof(dirEntry),
00271 "%s%s%s",
00272 path,
00273 path[strlen(path) - 1] == '/' ? "" : "/",
00274 basefile);
00275
00276 if (*dirEntry != '\0' && !stat(dirEntry, &stBuf));
00277 {
00278 if (S_ISREG(stBuf.st_mode))
00279 {
00280 fprintf(stdout, "Archiving '%s'.\n", dirEntry);
00281
00282
00283 rs = RetrieveRecords(orec->seriesinfo->seriesname, bcounter, ecounter, &err);
00284
00285 if (err != kARLErr_InvalidRange)
00286 {
00287 fprintf(stderr, "The file to be ingested (%s) has content from files that has been previously ingested. The previous content will be hidden (must use [! !] query to recover).\n", dirEntry);
00288 }
00289
00290 if (rs)
00291 {
00292 drms_close_records(rs, DRMS_FREE_RECORD);
00293 }
00294
00295 err = kARLErr_InvalidLog;
00296
00297
00298 seg = drms_segment_lookupnum(orec, 0);
00299
00300 if (seg)
00301 {
00302 char filepath[DRMS_MAXPATHLEN];
00303 TIME modtime;
00304
00305 snprintf(seg->filename, DRMS_MAXSEGFILENAME, "%s", basefile);
00306 drms_segment_filename(seg, filepath);
00307 CopyFile(dirEntry, filepath, &ioerr);
00308
00309 if (ioerr != 0)
00310 {
00311 fprintf(stderr, "Problem ingesting slony log, errno %d.\n", ioerr);
00312 err = kARLErr_FileIO;
00313 }
00314 else
00315 {
00316
00317 modtime = stBuf.st_mtime + UNIX_EPOCH;
00318
00319 drms_setkey_time(orec, kObsDate, modtime);
00320 drms_setkey_longlong(orec, kCBegin, bcounter);
00321 drms_setkey_longlong(orec, kCEnd, ecounter);
00322 drms_keyword_setdate(orec);
00323
00324 err = kARLErr_Success;
00325 }
00326 }
00327 }
00328 else
00329 {
00330 fprintf(stderr, "Not archiving '%s'; it doesn't look like a log file.\n", dirEntry);
00331 }
00332 }
00333 }
00334
00335 if (bcountertxt)
00336 {
00337 free(bcountertxt);
00338 }
00339
00340 if (ecountertxt)
00341 {
00342 free(ecountertxt);
00343 }
00344
00345 if (filetmp)
00346 {
00347 free(filetmp);
00348 }
00349
00350 return err;
00351 }
00352
00353 int DoIt(void)
00354 {
00355 ARLError_t err = kARLErr_Success;
00356
00357 const char *logs = cmdparams_get_str(&cmdparams, kLogs, NULL);
00358 const char *path = cmdparams_get_str(&cmdparams, kPath, NULL);
00359 const char *action = cmdparams_get_str(&cmdparams, kAction, NULL);
00360 const char *pat = cmdparams_get_str(&cmdparams, kLFRegEx, NULL);
00361 int64_t beg = cmdparams_get_int64(&cmdparams, kBegin, NULL);
00362 int64_t end = cmdparams_get_int64(&cmdparams, kEnd, NULL);
00363
00364 DRMS_RecordSet_t *rs = NULL;
00365 char **paths = NULL;
00366 int ipath;
00367 int irec;
00368
00369 struct stat stBuf;
00370
00371 int status = DRMS_SUCCESS;
00372 int ioerr = 0;
00373 size_t bwritten = 0;
00374
00375
00376 if (strcasecmp(action, kActionRetrieve) == 0)
00377 {
00378 rs = RetrieveRecords(logs, beg, end, &err);
00379
00380 if (!err && rs && rs->n > 0)
00381 {
00382 if ((err = GetLogPaths(rs, &paths)) == kARLErr_Success)
00383 {
00384
00385 if (!stat(path, &stBuf))
00386 {
00387 if (S_ISREG(stBuf.st_mode))
00388 {
00389 if (rs->n == 1)
00390 {
00391
00392 bwritten = CopyFile(paths[0], path, &ioerr);
00393 if (bwritten != stBuf.st_size || ioerr != 0)
00394 {
00395 if (ioerr != 0)
00396 {
00397 fprintf(stderr, "Problem writing slony log file, errno %d.\n", ioerr);
00398 }
00399
00400 fprintf(stderr, "Error copying file from '%s' to '%s', bytes written %lld.\n", paths[0], path, (long long)bwritten);
00401 err = kARLErr_FileIO;
00402 }
00403 }
00404 else
00405 {
00406
00407 fprintf(stderr, "Archiving log files into a tar file not supported yet.\n");
00408 }
00409 }
00410 else if (S_ISDIR(stBuf.st_mode))
00411 {
00412 char outpath[PATH_MAX];
00413 char *pbase = NULL;
00414
00415
00416 for (irec = 0; irec < rs->n; irec++)
00417 {
00418 pbase = strrchr(paths[irec], '/');
00419 if (pbase)
00420 {
00421 snprintf(outpath, sizeof(outpath), "%s/%s", path, pbase + 1);
00422 }
00423 else
00424 {
00425 snprintf(outpath, sizeof(outpath), "%s/%s", path, paths[irec]);
00426 }
00427
00428 if (!stat(paths[irec], &stBuf))
00429 {
00430 bwritten = CopyFile(paths[irec], outpath, &ioerr);
00431 if (bwritten != stBuf.st_size || ioerr != 0)
00432 {
00433 if (ioerr != 0)
00434 {
00435 fprintf(stderr, "Problem writing slony log file, errno %d.\n", ioerr);
00436 }
00437
00438 fprintf(stderr, "Error copying file from '%s' to '%s', bytes writen %lld.\n", paths[irec], outpath, (long long)bwritten);
00439 err = kARLErr_FileIO;
00440
00441 break;
00442 }
00443 }
00444 else
00445 {
00446
00447 fprintf(stderr, "File '%s' is not a valid regular file.\n", paths[irec]);
00448 err = kARLErr_FileIO;
00449 break;
00450 }
00451 }
00452 }
00453 else
00454 {
00455
00456 fprintf(stderr, "Unsupported file type for argument '%s'.\n", path);
00457 err = kARLErr_Argument;
00458 }
00459 }
00460 else
00461 {
00462
00463 fprintf(stderr, "File '%s' is not a valid directory or regular file.\n", path);
00464 err = kARLErr_FileIO;
00465 }
00466 }
00467 else
00468 {
00469 fprintf(stderr, "Error fetching log files from SUMS.\n");
00470 }
00471 }
00472 else
00473 {
00474
00475 fprintf(stderr, "Invalid log-file dataseries (or series is empty).\n");
00476 err = kARLErr_LogFileSeries;
00477 }
00478
00479 if (paths)
00480 {
00481 for (ipath = 0; ipath < rs->n; ipath++)
00482 {
00483 if (paths[ipath])
00484 {
00485 free(paths[ipath]);
00486 }
00487 }
00488
00489 free(paths);
00490 }
00491
00492 if (rs)
00493 {
00494 drms_close_records(rs, DRMS_FREE_RECORD);
00495 }
00496 }
00497 else if (strcasecmp(action, kActionStore) == 0)
00498 {
00499
00500
00501 if (!stat(path, &stBuf))
00502 {
00503 if (S_ISREG(stBuf.st_mode))
00504 {
00505
00506 }
00507 else if (S_ISDIR(stBuf.st_mode))
00508 {
00509
00510 struct dirent **filelist = NULL;
00511 struct dirent *entry = NULL;
00512 int nfiles = -1;
00513 int ifile;
00514 char *oneFile = NULL;
00515 DRMS_RecordSet_t *rsouttmp = NULL;
00516 DRMS_RecordSet_t *rsout = NULL;
00517 regex_t regexp;
00518
00519 if ((nfiles = scandir(path, &filelist, NULL, NULL)) > 0 &&
00520 filelist != NULL)
00521 {
00522
00523
00524 char *logstmp = strdup(logs);
00525
00526 rsouttmp = drms_create_records(drms_env, nfiles, logstmp, DRMS_PERMANENT, &status);
00527 rsout = malloc(sizeof(DRMS_RecordSet_t));
00528 memset(rsout, 0, sizeof(DRMS_RecordSet_t));
00529
00530 free(logstmp);
00531
00532
00533 if (regcomp(®exp, pat, (REG_EXTENDED | REG_ICASE)) != 0)
00534 {
00535 fprintf(stderr, "Bad regular expression '%s'.\n", pat);
00536 err = kARLErr_Argument;
00537 }
00538 else
00539 {
00540 irec = 0;
00541 for (ifile = 0; ifile < nfiles; ifile++)
00542 {
00543 entry = filelist[ifile];
00544 if (entry != NULL)
00545 {
00546 DRMS_Record_t *orec = rsouttmp->records[irec];
00547 ARLError_t ret;
00548
00549 oneFile = entry->d_name;
00550 ret = IngestFile(path, oneFile, orec, ®exp);
00551 if (ret == kARLErr_Success)
00552 {
00553 drms_merge_record(rsout, rsouttmp->records[irec]);
00554 rsouttmp->records[irec] = NULL;
00555 irec++;
00556 }
00557
00558 free(entry);
00559 }
00560 }
00561 }
00562
00563 free(filelist);
00564 }
00565
00566 if (rsout)
00567 {
00568 drms_close_records(rsout, DRMS_INSERT_RECORD);
00569 }
00570
00571 if (rsouttmp)
00572 {
00573 drms_close_records(rsouttmp, DRMS_FREE_RECORD);
00574 }
00575
00576 regfree(®exp);
00577 }
00578 else
00579 {
00580
00581 fprintf(stderr, "Unsupported file type for argument '%s'.\n", path);
00582 err = kARLErr_Argument;
00583 }
00584 }
00585 else
00586 {
00587
00588 fprintf(stderr, "File '%s' is not a valid directory or regular file.\n", path);
00589 err = kARLErr_FileIO;
00590 }
00591 }
00592 else
00593 {
00594
00595
00596 }
00597
00598 return err;
00599 }