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:
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

Reply via email to