Permalink
Browse files

Greatly simplified the architecture.

Logging now actually works (no more bus errors :) ).
The buffer gets processed in a C extension running in a logger thread from the calling ruby code.


git-svn-id: svn+ssh://rubyforge.org/var/svn/alogr/trunk@2 5d4fd1e0-7adf-40a7-adde-e9af6235188f
  • Loading branch information...
1 parent 573e9f1 commit dfb4133fab1d614ce4801888bdf18a32b920c088 wayneeseguin committed Sep 17, 2007
Showing with 183 additions and 311 deletions.
  1. +43 −1 README
  2. +6 −0 TODO
  3. +0 −37 ext/aio/aio_log.h
  4. +0 −156 ext/aio/aio_signal.h
  5. +52 −93 ext/alogr_ext.c
  6. +13 −6 lib/alogr.rb
  7. +26 −0 specs/base.rb
  8. +13 −0 specs/default.rb
  9. 0 specs/many_logs.rb
  10. 0 specs/regexen_logs.rb
  11. +30 −0 specs/two_logs.rb
  12. +0 −5 tests/test1.rb
  13. +0 −13 tests/test2.rb
View
@@ -54,6 +54,47 @@ $logger = AlogR.new(:log => "/Users/wayne/projects/ruby/alogr/trunk/log/producti
require "lib/alogr"
$logger = AlogR.new(
:log => "/Users/wayne/projects/ruby/alogr/trunk/log/production.log",
+:error => "/Users/wayne/projects/ruby/alogr/trunk/log/error.log"
+)
+
+"(1)this should go to the production log\n".log
+
+"(2)this should go to error log\n".log(:error)
+
+"(3)error\n".log :error
+
+"(4)production\n".log :info
+
+"(5)error".log :error
+
+
+* Example 3
+require "lib/alogr"
+$logger = AlogR.new(
+:log => "/Users/wayne/projects/ruby/alogr/trunk/log/production.log",
+:error => "/Users/wayne/projects/ruby/alogr/trunk/log/error.log",
+:info => "/Users/wayne/projects/ruby/alogr/trunk/log/info.log",
+:warning => "/Users/wayne/projects/ruby/alogr/trunk/log/warning.log"
+)
+
+"this should go to info log\n".log
+
+"this should go to error log\n".log(:error)
+
+"this should go to production log\n".log(:warning)
+
+"error".log :error
+
+"warning\n".log :warning
+
+"info\n".log :info
+
+"yetanother error\n".log :error
+
+* Example 4
+require "lib/alogr"
+$logger = AlogR.new(
+:log => "/Users/wayne/projects/ruby/alogr/trunk/log/production.log",
:error => "/Users/wayne/projects/ruby/alogr/trunk/log/error.log",
:info => "/Users/wayne/projects/ruby/alogr/trunk/log/info.log",
/paypal => "/Users/wayne/projects/ruby/alogr/trunk/log/paypal.log"
@@ -62,7 +103,8 @@ $logger = AlogR.new(
"this should go to error log".log(:error)
"this should go to production log".log(:warning)
-* If line matches a regexp then sent log/paypal.log as well as production.log
+* Example 4:
+If line matches a regexp then sent log/paypal.log as well as production.log
AlogR.new(:log => "log/production.log", /paypal/ => "log/paypal.log")
Gets logged to both
View
@@ -0,0 +1,6 @@
+* Create gemspec
+* Create rake tasks:
+** rake install
+** rake package
+* Allow for specifying either absolute log paths or relative log paths with root directory.
+* Allow for regexen
View
@@ -1,37 +0,0 @@
-// Asynchronously log the string of specified length to given file
-int aio_log(void * string, int length, char * file_name) {
- printf("() aio_log '%s' > %s\n", string, file_name);
-
- int done = 0;
- int error;
- int file_descriptor;
-
- if ((file_descriptor = open(file_name, O_WRONLY | O_CREAT | O_APPEND)) == -1) {
- fprintf(stderr, "Failed to open %s: %s\n", file_name, strerror(errno));
- return 1;
- }
-
- if (init_signal(SIG_AIO) == -1) {
- perror("Failed to initialize signal");
- return 1;
- }
-
- if (init_write(file_descriptor, SIG_AIO, string, length) == -1) {
- perror("Failed to initate the write");
- return 1;
- }
-
- for ( ; ; ) {
- done = suspend_until_done_or_timeout(); // Wait for the aio complete signal or timeout
- if (!done) {
- if (done = getdone()) {
- if (error = geterror()) {
- fprintf(stderr, "Failed to log:%s\n", strerror(error));
- }
- }
- } else {
- fprintf(stderr, "Logging successful, %d bytes\n", getbytes());
- break; // break out of for loop
- }
- }
-}
View
@@ -1,156 +0,0 @@
-#include "aio.h"
-#include "errno.h"
-#include "signal.h"
-//#include "restart.h" // r_read, r_write, etc
-
-static struct aiocb aiocb;
-static sig_atomic_t doneflag;
-static int fdout;
-static int globalerror;
-static int totalbytes;
-
-static int readstart();
-static void seterror(int error);
-
-static void aiohandler(int signo, siginfo_t *info, void *context) {
- int myerrno;
- int mystatus;
- int serrno;
-
- serrno = errno;
- myerrno = aio_error(&aiocb);
-
- if (myerrno == EINPROGRESS) {
- errno = serrno;
- return;
- }
-
- if (myerrno) {
- seterror(myerrno);
- errno = serrno;
- return;
- }
-
- mystatus = aio_return(&aiocb);
- totalbytes += mystatus;
-
- // Handling of regexen should go somewhere around here
-
- if (mystatus == 0) {
- doneflag = 1;
- }
-
- errno = serrno;
-}
-
-// start an asynchronous read
-static int readstart() {
- int error;
- if (error = aio_read(&aiocb)) {
- seterror(errno);
- }
- return error;
-}
-
-// start an asynchronous write
-static int writestart() {
- int error;
- if (error = aio_write(&aiocb)) {
- seterror(errno);
- }
- return error;
-}
-
-// update globalerror if zero
-static void seterror(int error) {
- if (!globalerror) {
- globalerror = error;
- }
- doneflag = 1;
-}
-
-/* --------------------------Public Functions ---------------------------- */
-// Get the total number of bytes
-int getbytes() {
- if (doneflag){
- return totalbytes;
- }
- errno = EINVAL;
- return -1;
-}
-
-// Check if done
-int getdone() {
- return doneflag;
-}
-
-// Return the globalerror value if process is done
-int geterror() {
- if (doneflag) {
- return globalerror;
- }
- errno = EINVAL;
- return errno;
-}
-
-int init_read(int fdread, int fdwrite, int signo, char *buf, int bufsize) {
- // Setup control block
- aiocb.aio_fildes = fdread;
- aiocb.aio_offset = 0;
- aiocb.aio_buf = (void *) buf;
- aiocb.aio_nbytes = bufsize;
-
- // Signal handling
- aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
- aiocb.aio_sigevent.sigev_signo = signo;
- aiocb.aio_sigevent.sigev_value.sival_ptr = &aiocb;
- fdout = fdwrite;
- doneflag = 0;
- globalerror = 0;
- totalbytes = 0;
- return readstart(); // Initiate the aio_read call
-}
-
-int init_write(int fdwrite, int signal_number, char *buffer, int buffer_size) {
- // Setup control block
- aiocb.aio_fildes = fdwrite;
- aiocb.aio_offset = 0; // Should be ignored if file is in append-mode
- aiocb.aio_buf = (void *)buffer;
- aiocb.aio_nbytes = buffer_size;
-
- // Signal handling
- aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
- aiocb.aio_sigevent.sigev_signo = signal_number;
- aiocb.aio_sigevent.sigev_value.sival_ptr = &aiocb;
-
- aiocb.aio_sigevent.sigev_signo = SIGUSR1;
- // Initialize variables
- fdout = fdwrite;
- doneflag = 0;
- globalerror = 0;
- totalbytes = 0;
-
- return writestart(); // Initiate the aio_write call
-}
-
-// set up the handler for the async I/O
-int init_signal(int signo) {
- struct sigaction newact;
-
- newact.sa_sigaction = aiohandler;
- newact.sa_flags = SA_SIGINFO;
- if ((sigemptyset(&newact.sa_mask) == -1) ||
- (sigaction(signo, &newact, NULL) == -1)) {
- return -1;
- }
- return 0;
-}
-
-// return 1 if done, 0 otherwise
-int suspend_until_done_or_timeout() {
- const struct aiocb *aiocblist;
-
- aiocblist = &aiocb;
- aio_suspend(&aiocblist, 1, NULL);
- return doneflag;
-}
Oops, something went wrong.

0 comments on commit dfb4133

Please sign in to comment.