Browse Source

Add sys.stdout & sys.stderr logging for pep333 worker

Yann Weber 4 years ago
parent
commit
d3c9e2de42
2 changed files with 58 additions and 2 deletions
  1. 8
    0
      include/pyworker.h
  2. 50
    2
      src/pyworker.c

+ 8
- 0
include/pyworker.h View File

@@ -150,6 +150,14 @@ int worker_piper(void*);
150 150
  */
151 151
 void worker_piper_sighandler(int);
152 152
 
153
+/**@brief empty pipes and log content for pep333 workers
154
+ * @todo enhance logging : 1 lines per logline + line counter ?
155
+ * @param int pipes for stdout
156
+ * @param int pipes for stderr
157
+ * @param PyObject[2] python flush methods
158
+ */
159
+void worker_log_pipes(int, int, PyObject*[2]);
160
+
153 161
 /**@brief Attempt to read the request size from ctl pipe
154 162
  * @param int ctl pipe read fd
155 163
  * @param size_t* rep_sz

+ 50
- 2
src/pyworker.c View File

@@ -92,6 +92,7 @@ int work333(int wrk_id, int semid)
92 92
 		libpyfcgi.out = out_stream;
93 93
 		libpyfcgi.in = in_stream;
94 94
 		args = Py_BuildValue("OO", environ, start_response);
95
+		// Call application function
95 96
 		entry_ret = PyObject_CallObject(entry_fun, args);
96 97
 		if(entry_ret && entry_ret != Py_None )
97 98
 		{
@@ -119,8 +120,7 @@ int work333(int wrk_id, int semid)
119 120
 		Py_DECREF(args);
120 121
 		Py_DECREF(environ);
121 122
 		// flush & logs pystdout & pystderr
122
-		PyObject_CallObject(pyflush[0], NULL);
123
-		PyObject_CallObject(pyflush[1], NULL);
123
+		worker_log_pipes(pipe_out[0], pipe_err[0], pyflush);
124 124
 
125 125
 		FCGX_FClose(out_stream);
126 126
 		FCGX_FClose(in_stream);
@@ -483,6 +483,54 @@ int worker_piper(void *ptr)
483 483
 	return 0;
484 484
 }
485 485
 
486
+void worker_log_pipes(int pipe_std, int pipe_err, PyObject *flush[2])
487
+{
488
+	size_t ret;
489
+	char buff[4096];
490
+	int i, poll_ret;
491
+	int loglevels[2] = {LOG_INFO, LOG_WARNING};
492
+	struct pollfd fds[2];
493
+	short isflush[2] = {0,0};
494
+	char *outnames[2] = {"sys.stdout", "sys.stderr"};
495
+
496
+	fds[0].fd = pipe_std;
497
+	fds[1].fd = pipe_err;
498
+	fds[0].events = fds[1].events = POLLIN;
499
+	fds[0].revents = fds[1].revents = 0;
500
+
501
+	for(i=0; i<2; i++)
502
+	{
503
+		do
504
+		{
505
+			poll_ret = poll(&(fds[i]), 1, 0);
506
+			if(poll_ret)
507
+			{
508
+				ret = read(pipe_std, buff, 4096);
509
+				if(ret == -1)
510
+				{
511
+					pyfcgi_log(LOG_ERR, "Error reading python %s pipe : %s",
512
+						outnames[i], strerror(errno));
513
+					exit(PYFCGI_WORKER_FAIL);
514
+				}
515
+				pyfcgi_log(loglevels[i], "Pyton %s  : '%s'",
516
+					outnames[i], buff);
517
+			}
518
+			if(!isflush[i] && (!poll_ret || ret < 4096))
519
+			{
520
+				isflush[i] = 1;
521
+				PyObject_CallObject(flush[i], NULL);
522
+				if(PyErr_Occurred())
523
+				{
524
+					pyfcgi_log(LOG_ERR, "Exception while flushing %s",
525
+						outnames[i]);
526
+					log_expt(LOG_ERR);
527
+					exit(PYFCGI_WORKER_FAIL);
528
+				}
529
+			}
530
+		}while(poll_ret && !isflush[i]);
531
+	}
532
+}
533
+
486 534
 void worker_piper_sighandler(int signum)
487 535
 {
488 536
 	worker_piper_sigrcv = 1;

Loading…
Cancel
Save