macruby-asl-logger 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE ADDED
@@ -0,0 +1,55 @@
1
+ Copyright (c) <2010> Eloy Duran, <eloy.de.enige@gmail.com>
2
+
3
+ This software is available under the Ruby license:
4
+
5
+ ===============================================================================
6
+
7
+ You can redistribute it and/or modify it under either the terms of the GPL, or
8
+ the conditions below:
9
+
10
+ 1. You may make and give away verbatim copies of the source form of the
11
+ software without restriction, provided that you duplicate all of the
12
+ original copyright notices and associated disclaimers.
13
+
14
+ 2. You may modify your copy of the software in any way, provided that
15
+ you do at least ONE of the following:
16
+
17
+ a) place your modifications in the Public Domain or otherwise make them
18
+ Freely Available, such as by posting said modifications to Usenet or
19
+ an equivalent medium, or by allowing the author to include your
20
+ modifications in the software.
21
+
22
+ b) use the modified software only within your corporation or
23
+ organization.
24
+
25
+ c) rename any non-standard executables so the names do not conflict with
26
+ standard executables, which must also be provided.
27
+
28
+ d) make other distribution arrangements with the author.
29
+
30
+ 3. You may distribute the software in object code or executable form,
31
+ provided that you do at least ONE of the following:
32
+
33
+ a) distribute the executables and library files of the software,
34
+ together with instructions (in the manual page or equivalent) on
35
+ where to get the original distribution.
36
+
37
+ b) accompany the distribution with the machine-readable source of the
38
+ software.
39
+
40
+ c) give non-standard executables non-standard names, with instructions
41
+ on where to get the original software distribution.
42
+
43
+ d) make other distribution arrangements with the author.
44
+
45
+ 4. You may modify and include the part of the software into any other
46
+ software (possibly commercial).
47
+
48
+ 5. The scripts and library files supplied as input to or produced as output
49
+ from the software do not automatically fall under the copyright of the
50
+ software, but belong to whomever generated them, and may be sold
51
+ commercially, and may be aggregated with this software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
54
+ WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
55
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
data/README ADDED
@@ -0,0 +1,9 @@
1
+ Currently a very naive implementation, which might be updated to resemble the
2
+ existing Ruby logger API more closely.
3
+
4
+ Also, this release (0.1.0) probably comes packed with bugs! :P This should be
5
+ considered a pre-release, but I will *not* use those stupid pre-release gem
6
+ version thingies.
7
+
8
+ This software is available under the Ruby license. (See LICENSE for details.)
9
+ Copyright (c) <2010> Eloy Duran, <eloy.de.enige@gmail.com>
@@ -0,0 +1,32 @@
1
+ desc "Build the ext"
2
+ task :build do
3
+ sh "cd ext && macruby extconf.rb && make"
4
+ end
5
+
6
+ desc "Clean"
7
+ task :clean do
8
+ rm "ext/Makefile"
9
+ rm "ext/logger.o"
10
+ rm "ext/logger.bundle"
11
+ end
12
+
13
+ desc "Run the specs"
14
+ task :spec do
15
+ sh "macruby -r #{FileList['spec/*_spec.rb'].join(' -r ')} -e ''"
16
+ end
17
+
18
+ begin
19
+ require 'jeweler'
20
+ Jeweler::Tasks.new do |gemspec|
21
+ gemspec.name = "macruby-asl-logger"
22
+ gemspec.summary = gemspec.description = "A MacRuby wrapper of the Apple System Log facility"
23
+ gemspec.homepage = "http://github.com/alloy/macruby-asl-logger"
24
+
25
+ gemspec.authors = ["Eloy Duran"]
26
+ gemspec.email = "eloy.de.enige@gmail.com"
27
+
28
+ gemspec.required_ruby_version = ::Gem::Requirement.new("~> 1.9")
29
+ gemspec.files.delete '.gitignore'
30
+ end
31
+ rescue LoadError
32
+ end
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS << ' -std=c99'
4
+ create_makefile('logger')
@@ -0,0 +1,128 @@
1
+ #include <fcntl.h>
2
+ #include <asl.h>
3
+
4
+ #include "ruby/ruby.h"
5
+ #include "ruby/io.h"
6
+
7
+ VALUE cLogger;
8
+
9
+ struct mr_logger {
10
+ aslclient asl_client;
11
+ VALUE file_descriptor;
12
+ // VALUE file_descriptors;
13
+ };
14
+
15
+ uint32_t LoggerDefaultASLOptions = ASL_OPT_NO_DELAY | ASL_OPT_STDERR | ASL_OPT_NO_REMOTE;
16
+
17
+ static VALUE
18
+ mr_logger_allocate(VALUE klass, SEL sel)
19
+ {
20
+ VALUE obj;
21
+ struct mr_logger *logger;
22
+
23
+ obj = Data_Make_Struct(klass, struct mr_logger, NULL, NULL, logger);
24
+ // logger->file_descriptors = rb_ary_new();
25
+
26
+ return obj;
27
+ }
28
+
29
+ // so initialize *always* has to take variadic args?
30
+ static VALUE
31
+ mr_logger_initialize(VALUE self, SEL sel, int argc, VALUE *argv)
32
+ {
33
+ if (argc != 1) {
34
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
35
+ }
36
+
37
+ struct mr_logger *logger;
38
+ Data_Get_Struct(self, struct mr_logger, logger);
39
+
40
+ // If no facility is specified, use "com.apple.console"
41
+ // TODO: add custom facility
42
+ logger->asl_client = asl_open(NULL, "com.apple.console", LoggerDefaultASLOptions);
43
+
44
+ VALUE io = argv[0];
45
+ if (rb_respond_to(io, rb_intern("write")) == Qfalse || rb_respond_to(io, rb_intern("close")) == Qfalse) {
46
+ // TODO: currently I just assume it's a string if it's not an IO object
47
+ const char *fname = rb_str_cstr(io);
48
+ int mode = O_WRONLY | O_APPEND;
49
+ int fd = open(fname, mode);
50
+ io = rb_io_fdopen(fd, mode, fname);
51
+ }
52
+ logger->file_descriptor = io;
53
+
54
+ if (asl_add_log_file(logger->asl_client, ExtractIOStruct(io)->fd) == 0) {
55
+ // printf("success!\n");
56
+ }
57
+
58
+ return self;
59
+ }
60
+
61
+ void
62
+ mr_logger_close(VALUE self, SEL sel)
63
+ {
64
+ struct mr_logger *logger;
65
+ Data_Get_Struct(self, struct mr_logger, logger);
66
+
67
+ rb_io_close(logger->file_descriptor);
68
+ asl_close(logger->asl_client);
69
+ }
70
+
71
+ static void
72
+ logger_add(VALUE self, int level, VALUE text)
73
+ {
74
+ struct mr_logger *logger;
75
+ Data_Get_Struct(self, struct mr_logger, logger);
76
+
77
+ // TODO: good way to check if it's open
78
+ if (ExtractIOStruct(logger->file_descriptor)->write_fd != -1) {
79
+ aslmsg msg = asl_new(ASL_TYPE_MSG);
80
+ asl_set(msg, ASL_KEY_FACILITY, "com.apple.console");
81
+ asl_log(logger->asl_client, msg, level, "%s", rb_str_cstr(text));
82
+ asl_free(msg);
83
+ }
84
+ else {
85
+ rb_warn("log writing failed. closed stream");
86
+ }
87
+ }
88
+
89
+ void
90
+ mr_logger_add(VALUE self, SEL sel, VALUE level, VALUE text)
91
+ {
92
+ logger_add(self, (level == Qnil ? ASL_LEVEL_ALERT : FIX2INT(level)), text);
93
+ }
94
+
95
+ void
96
+ mr_logger_debug(VALUE self, SEL sel, VALUE text)
97
+ {
98
+ logger_add(self, ASL_LEVEL_DEBUG, text);
99
+ }
100
+
101
+ void
102
+ Init_logger()
103
+ {
104
+ cLogger = rb_define_class("Logger", rb_cObject);
105
+
106
+ rb_objc_define_method(*(VALUE *)cLogger, "alloc", mr_logger_allocate, 0);
107
+
108
+ rb_objc_define_method(cLogger, "initialize", mr_logger_initialize, -1);
109
+ rb_objc_define_method(cLogger, "add", mr_logger_add, 2);
110
+ rb_objc_define_method(cLogger, "debug", mr_logger_debug, 1);
111
+ rb_objc_define_method(cLogger, "close", mr_logger_close, 0);
112
+
113
+ rb_define_alias(cLogger, "log", "add");
114
+
115
+ rb_define_const(cLogger, "EMERGENCY", INT2FIX(ASL_LEVEL_EMERG));
116
+ rb_define_const(cLogger, "ALERT", INT2FIX(ASL_LEVEL_ALERT));
117
+ rb_define_const(cLogger, "CRITICAL", INT2FIX(ASL_LEVEL_CRIT));
118
+ rb_define_const(cLogger, "ERROR", INT2FIX(ASL_LEVEL_ERR));
119
+ rb_define_const(cLogger, "WARNING", INT2FIX(ASL_LEVEL_WARNING));
120
+ rb_define_const(cLogger, "NOTICE", INT2FIX(ASL_LEVEL_NOTICE));
121
+ rb_define_const(cLogger, "INFO", INT2FIX(ASL_LEVEL_INFO));
122
+ rb_define_const(cLogger, "DEBUG", INT2FIX(ASL_LEVEL_DEBUG));
123
+
124
+ // Ruby's stdlib Logger constant aliases
125
+ rb_define_const(cLogger, "UNKNOWN", INT2FIX(ASL_LEVEL_ALERT));
126
+ rb_define_const(cLogger, "FATAL", INT2FIX(ASL_LEVEL_CRIT));
127
+ rb_define_const(cLogger, "WARN", INT2FIX(ASL_LEVEL_WARNING));
128
+ }
@@ -0,0 +1,83 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe "Logger#add" do
4
+ before do
5
+ @path = tmp("test_log.log")
6
+ @log_file = File.open(@path, "w+")
7
+ # @logger = Logger.new(@path)
8
+ @logger = Logger.new(@log_file)
9
+ end
10
+
11
+ after do
12
+ # @logger.close
13
+ @log_file.close unless @log_file.closed?
14
+ File.unlink(@path) if File.exists?(@path)
15
+ end
16
+
17
+ it "writes a new message to the logger" do
18
+ @logger.add(Logger::WARN, "Test")
19
+ @log_file.rewind
20
+ message = @log_file.readlines.last
21
+ strip_metadata(message).should == "<Warning>: Test\n"
22
+ end
23
+
24
+ it "receives a severity" do
25
+ @logger.log(Logger::INFO, "Info message")
26
+ @logger.log(Logger::DEBUG, "Debug message")
27
+ @logger.log(Logger::WARN, "Warn message")
28
+ @logger.log(Logger::ERROR, "Error message")
29
+ @logger.log(Logger::FATAL, "Fatal message")
30
+
31
+ @log_file.rewind
32
+
33
+ info, debug, warn, error, fatal = @log_file.readlines
34
+
35
+ strip_metadata(info).should == "<Info>: Info message\n"
36
+ strip_metadata(debug).should == "<Debug>: Debug message\n"
37
+ strip_metadata(warn).should == "<Warning>: Warn message\n"
38
+ strip_metadata(error).should == "<Error>: Error message\n"
39
+ # strip_metadata(fatal).should == "<Fatal>: Fatal message\n"
40
+ strip_metadata(fatal).should == "<Critical>: Fatal message\n"
41
+ end
42
+
43
+ it "receives a message" do
44
+ @logger.log(nil, "test")
45
+ @log_file.rewind
46
+ # strip_metadata(@log_file.readline).should == "ANY -- : test\n"
47
+ strip_metadata(@log_file.readline).should == "<Alert>: test\n"
48
+ end
49
+
50
+ # it "receives a program name" do
51
+ # @logger.log(nil, "test", "TestApp")
52
+ # @log_file.rewind
53
+ # LoggerSpecs::strip_date(@log_file.readline).should == "ANY -- TestApp: test\n"
54
+ # end
55
+ #
56
+ # it "receives a block" do
57
+ # lambda {
58
+ # @logger.log(nil, "test", "TestApp") do
59
+ # 1+1
60
+ # end
61
+ # }.should_not raise_error
62
+ # end
63
+ #
64
+ # it "calls the block if message is nil" do
65
+ # temp = 0
66
+ # lambda {
67
+ # @logger.log(nil, nil, "TestApp") do
68
+ # temp = 1+1
69
+ # end
70
+ # }.should_not raise_error
71
+ # temp.should == 2
72
+ # end
73
+ #
74
+ # it "ignores the block if the message is not nil" do
75
+ # temp = 0
76
+ # lambda {
77
+ # @logger.log(nil, "not nil", "TestApp") do
78
+ # temp = 1+1
79
+ # end
80
+ # }.should_not raise_error
81
+ # temp.should == 0
82
+ # end
83
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe "Logger#close" do
4
+ before do
5
+ @path = tmp("test_log.log")
6
+ @log_file = File.open(@path, "w+")
7
+ @logger = Logger.new(@path)
8
+ end
9
+
10
+ after do
11
+ @log_file.close unless @log_file.closed?
12
+ File.unlink(@path) if File.exists?(@path)
13
+ end
14
+
15
+ it "closes the logging device" do
16
+ @logger.close
17
+ lambda { @logger.add(nil, "Foo") }.should complain('log writing failed. closed stream')
18
+ end
19
+ end
@@ -0,0 +1,52 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ # describe "Logger#debug?" do
4
+ # before :each do
5
+ # @path = tmp("test_log.log")
6
+ # @log_file = File.open(@path, "w+")
7
+ # @logger = Logger.new(@path)
8
+ # end
9
+ #
10
+ # after :each do
11
+ # @logger.close
12
+ # @log_file.close unless @log_file.closed?
13
+ # File.unlink(@path) if File.exists?(@path)
14
+ # end
15
+ #
16
+ # it "returns true if severity level allows debug messages" do
17
+ # @logger.level = Logger::DEBUG
18
+ # @logger.debug?.should == true
19
+ # end
20
+ #
21
+ # it "returns false if severity level does not allow debug messages" do
22
+ # @logger.level = Logger::WARN
23
+ # @logger.debug?.should == false
24
+ # end
25
+ # end
26
+
27
+ describe "Logger#debug" do
28
+ before do
29
+ @path = tmp("test_log.log")
30
+ @log_file = File.open(@path, "w+")
31
+ # @logger = Logger.new(@path)
32
+ @logger = Logger.new(@log_file)
33
+ end
34
+
35
+ after do
36
+ @logger.close
37
+ @log_file.close unless @log_file.closed?
38
+ File.unlink(@path) if File.exists?(@path)
39
+ end
40
+
41
+ it "logs a DEBUG message" do
42
+ @logger.debug("test")
43
+ @log_file.rewind
44
+ strip_metadata(@log_file.readline).should == "<Debug>: test\n"
45
+ end
46
+
47
+ # it "accepts an application name with a block" do
48
+ # @logger.debug("MyApp") { "Test message" }
49
+ # @log_file.rewind
50
+ # strip_metadata(@log_file.readlines.first).should == "DEBUG -- MyApp: Test message\n"
51
+ # end
52
+ end
@@ -0,0 +1,36 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe "Logger.new" do
4
+ before do
5
+ @file_path = tmp("test_log.log")
6
+ @log_file = File.open(@file_path, "w+")
7
+ end
8
+
9
+ after do
10
+ @log_file.close unless @log_file.closed?
11
+ File.unlink(@file_path) if File.exists?(@file_path)
12
+ end
13
+
14
+ it "raises an ArgumentError when given more or less than 1 argument" do
15
+ lambda { Logger.new }.should.raise ArgumentError
16
+ lambda { Logger.new(@log_file, @log_file) }.should.raise ArgumentError
17
+ end
18
+
19
+ it "accepts a logging device as the first argument" do
20
+ l = Logger.new(@log_file)
21
+ l.add(Logger::WARN, "Test message")
22
+
23
+ @log_file.rewind
24
+ strip_metadata(@log_file.readline).should == "<Warning>: Test message\n"
25
+ l.close
26
+ end
27
+
28
+ it "accepts a path to a log file as the first argument" do
29
+ l = Logger.new(@file_path)
30
+ l.add(Logger::WARN, "Test message")
31
+
32
+ @log_file.rewind
33
+ strip_metadata(@log_file.readline).should == "<Warning>: Test message\n"
34
+ l.close
35
+ end
36
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe "Logger::Severity" do
4
+ it "defines Logger severity constants" do
5
+ Logger::EMERGENCY.should == 0
6
+ Logger::ALERT.should == 1
7
+ Logger::CRITICAL.should == 2
8
+ Logger::ERROR.should == 3
9
+ Logger::WARNING.should == 4
10
+ Logger::NOTICE.should == 5
11
+ Logger::INFO.should == 6
12
+ Logger::DEBUG.should == 7
13
+ end
14
+
15
+ it "aliases Ruby’s Logger constants to the compatible ones defined by ASL" do
16
+ Logger::DEBUG.should == Logger::DEBUG
17
+ Logger::INFO.should == Logger::INFO
18
+ Logger::WARN.should == Logger::WARNING
19
+ Logger::ERROR.should == Logger::ERROR
20
+ Logger::FATAL.should == Logger::CRITICAL
21
+ Logger::UNKNOWN.should == Logger::ALERT
22
+ end
23
+ end
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'bacon'
3
+
4
+ Bacon.summary_on_exit
5
+
6
+ require File.expand_path('../../ext/logger', __FILE__)
7
+
8
+ require 'tempfile'
9
+
10
+ class Bacon::Context
11
+ def tmp(name)
12
+ File.join(Dir.tmpdir, name)
13
+ end
14
+
15
+ def strip_metadata(log_line)
16
+ log_line.sub(/^.+macruby\[\d+\]\s/, '')
17
+ end
18
+
19
+ def complain(str)
20
+ lambda do |proc|
21
+ begin
22
+ stderr, $stderr = $stderr, IOStub.new
23
+ verbose, $VERBOSE = $VERBOSE, false
24
+
25
+ proc.call
26
+ $stderr.include?(str)
27
+ ensure
28
+ $stderr = stderr
29
+ $VERBOSE = verbose
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ class IOStub < String
36
+ def write(*str)
37
+ self << str.join
38
+ end
39
+
40
+ def print(*str)
41
+ write(str.join + $\.to_s)
42
+ end
43
+
44
+ def puts(*str)
45
+ write(str.collect { |s| s.to_s.chomp }.concat([nil]).join("\n"))
46
+ end
47
+
48
+ def printf(format, *args)
49
+ self << sprintf(format, *args)
50
+ end
51
+
52
+ def flush
53
+ self
54
+ end
55
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: macruby-asl-logger
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Eloy Duran
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-05-21 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A MacRuby wrapper of the Apple System Log facility
17
+ email: eloy.de.enige@gmail.com
18
+ executables: []
19
+
20
+ extensions:
21
+ - ext/extconf.rb
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README
25
+ files:
26
+ - README
27
+ - Rakefile
28
+ - ext/extconf.rb
29
+ - ext/logger.c
30
+ - spec/add_spec.rb
31
+ - spec/close_spec.rb
32
+ - spec/debug_spec.rb
33
+ - spec/new_spec.rb
34
+ - spec/severity_spec.rb
35
+ - spec/spec_helper.rb
36
+ - LICENSE
37
+ has_rdoc: true
38
+ homepage: http://github.com/alloy/macruby-asl-logger
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --charset=UTF-8
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ~>
49
+ - !ruby/object:Gem::Version
50
+ version: "1.9"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.5
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: A MacRuby wrapper of the Apple System Log facility
65
+ test_files:
66
+ - spec/add_spec.rb
67
+ - spec/close_spec.rb
68
+ - spec/debug_spec.rb
69
+ - spec/new_spec.rb
70
+ - spec/severity_spec.rb
71
+ - spec/spec_helper.rb