Patch for - Allow server logs to be remotely read - Mailing list pgsql-patches
From | Dhanaraj M |
---|---|
Subject | Patch for - Allow server logs to be remotely read |
Date | |
Msg-id | 448824F8.50706@sun.com Whole thread Raw |
Responses |
Re: Patch for - Allow server logs to be remotely read
|
List | pgsql-patches |
The patch is attached for the following TODO item: *Allow server logs to be remotely read. Steps: 1. When the server starts (**pg_ctl start)**, the path of the postmaster file is stored 2. The user can access the logfile using the following 2 functions: * pg_file_readlog(int linenumber) - Retrieves the string for the given line number * **pg_file_countlog() - Retrieves the number of lines existing in the logfile* I have implemented this based on the suggestions given in the hackers mailing list. If you know a better way, please share it with me. Waiting for your reply. Thanks Dhanaraj *** ./contrib/adminpack/adminpack.c.orig Thu Jun 8 17:04:42 2006 --- ./contrib/adminpack/adminpack.c Thu Jun 8 18:34:37 2006 *************** *** 24,30 **** --- 24,32 ---- #include "catalog/pg_type.h" #include "funcapi.h" #include "utils/datetime.h" + #include "utils/builtins.h" + #define GET_TEXT(cstrp) DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(cstrp))) #ifdef WIN32 *************** *** 48,58 **** --- 50,64 ---- Datum pg_file_rename(PG_FUNCTION_ARGS); Datum pg_file_unlink(PG_FUNCTION_ARGS); Datum pg_logdir_ls(PG_FUNCTION_ARGS); + Datum pg_file_readlog(PG_FUNCTION_ARGS); + Datum pg_file_countlog(); PG_FUNCTION_INFO_V1(pg_file_write); PG_FUNCTION_INFO_V1(pg_file_rename); PG_FUNCTION_INFO_V1(pg_file_unlink); PG_FUNCTION_INFO_V1(pg_logdir_ls); + PG_FUNCTION_INFO_V1(pg_file_readlog); + PG_FUNCTION_INFO_V1(pg_file_countlog); typedef struct { *************** *** 390,392 **** --- 396,520 ---- FreeDir(fctx->dirdesc); SRF_RETURN_DONE(funcctx); } + + /* Retrieves n-th line from the postmaster logfile */ + + Datum pg_file_readlog(PG_FUNCTION_ARGS) + { + char c, buffer[MAXPGPATH]; + char file_path2[MAXPGPATH], file_path1[MAXPGPATH]; + int64 linenumber = PG_GETARG_INT64(0); + FILE *filePtr1, *filePtr2; + int64 count=1; + int index=0; + + if(OutputFileName[0]) + { + filePtr1 = fopen(OutputFileName, "r"); + } + else + { + /* Finds the logfile path from postmasterlog_path file */ + snprintf(file_path1, MAXPGPATH, "%s/postmasterlog_path", DataDir); + filePtr2 = fopen(file_path1, "r"); + if(filePtr2 != NULL) + { + memset(file_path2, 0, MAXPGPATH); + fread(file_path2, 1, MAXPGPATH, filePtr2); + } + else + { + snprintf(buffer, MAXPGPATH, "Could not find the logfile path in: %s", file_path1); + ereport(ERROR, (errcode_for_file_access(), errmsg(buffer))); + } + + fclose(filePtr2); + filePtr1 = fopen(file_path2, "r"); + } + + memset(buffer, 0, MAXPGPATH); + + if(filePtr1 == NULL) + { + snprintf(buffer, MAXPGPATH, "Logfile: %s - Not found", file_path2); + ereport(ERROR, (errcode_for_file_access(), errmsg(buffer))); + } + + /* Reads the logfile and extract n-th line */ + while( (c= fgetc(filePtr1))!=EOF) + { + if (linenumber == count) + { + buffer[index] = c; + index++; + } + + /* Counts the number of lines */ + if(c=='\n') + { + count++; + } + } + + if(count <= linenumber) + { + sprintf(buffer, "Given line number does not exist"); + ereport(ERROR, (errcode_for_file_access(), errmsg(buffer))); + } + + fclose(filePtr1); + PG_RETURN_TEXT_P(GET_TEXT(buffer)); + } + + /* Counts the number of lines in the postmaster logfile */ + + Datum pg_file_countlog() + { + char c, buffer[MAXPGPATH]; + char file_path2[MAXPGPATH], file_path1[MAXPGPATH]; + FILE *filePtr1, *filePtr2; + int64 count=1; + + if(OutputFileName[0]) + { + filePtr1 = fopen(OutputFileName, "r"); + } + else + { + /* Finds the logfile path from postmasterlog_path file */ + snprintf(file_path1, MAXPGPATH, "%s/postmasterlog_path", DataDir); + filePtr2 = fopen(file_path1, "r"); + if(filePtr2 != NULL) + { + memset(file_path2, 0, MAXPGPATH); + fread(file_path2, 1, MAXPGPATH, filePtr2); + } + else + { + snprintf(buffer, MAXPGPATH, "Could not find the logfile path in: %s", file_path1); + ereport(ERROR, (errcode_for_file_access(), errmsg(buffer))); + } + + fclose(filePtr2); + filePtr1 = fopen(file_path2, "r"); + } + + memset(buffer, 0, MAXPGPATH); + + if(filePtr1== NULL) + { + snprintf(buffer, MAXPGPATH, "Logfile: %s - Not found", file_path2); + ereport(ERROR, (errcode_for_file_access(), errmsg(buffer))); + } + + /* Counts the number of lines */ + while( (c= fgetc(filePtr1))!=EOF) + { + if(c=='\n') + count++; + } + + fclose(filePtr1); + PG_RETURN_INT64(count-1); + } + *** ./contrib/adminpack/adminpack.sql.in.orig Thu Jun 8 17:05:16 2006 --- ./contrib/adminpack/adminpack.sql.in Thu Jun 8 17:06:11 2006 *************** *** 24,30 **** --- 24,37 ---- AS 'MODULE_PATHNAME', 'pg_logdir_ls' LANGUAGE C VOLATILE STRICT; + CREATE FUNCTION pg_catalog.pg_file_readlog(bigint) RETURNS text + AS 'MODULE_PATHNAME', 'pg_file_readlog' + LANGUAGE C VOLATILE STRICT; + CREATE FUNCTION pg_catalog.pg_file_countlog() RETURNS bigint + AS 'MODULE_PATHNAME', 'pg_file_countlog' + LANGUAGE C VOLATILE STRICT; + /* compatibility redefines */ CREATE FUNCTION pg_catalog.pg_logfile_rotate() RETURNS int4 *** ./src/bin/pg_ctl/pg_ctl.c.orig Thu Jun 8 16:47:20 2006 --- ./src/bin/pg_ctl/pg_ctl.c Thu Jun 8 17:32:48 2006 *************** *** 1719,1724 **** --- 1719,1752 ---- snprintf(conf_file, MAXPGPATH, "%s/postgresql.conf", pg_data); } + /* Store the postmaster logfile name in postmasterlog_path file */ + + if( (ctl_command == START_COMMAND) || (ctl_command == RESTART_COMMAND) || (ctl_command == RELOAD_COMMAND)) + { + FILE *filePtr; + char file_path[MAXPGPATH]; + char *cwd; + + snprintf(file_path, MAXPGPATH, "%s/postmasterlog_path", pg_data); + filePtr = fopen(file_path, "w+"); + + if(log_file[0] == '/') + { + fprintf(filePtr,"%s", log_file); + } + else + { + /* Append the current path string with the logfile name */ + if ((cwd = getcwd(NULL, 64)) != NULL) + { + fprintf(filePtr, "%s/%s", cwd, log_file); + free(cwd); + } + } + fclose(filePtr); + } + + switch (ctl_command) { case STATUS_COMMAND:
pgsql-patches by date: