semantic_logger 2.3.1 → 2.4.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.
- checksums.yaml +4 -4
- data/README.md +50 -42
- data/lib/semantic_logger.rb +1 -0
- data/lib/semantic_logger/appender/file.rb +18 -7
- data/lib/semantic_logger/appender/syslog.rb +249 -0
- data/lib/semantic_logger/semantic_logger.rb +8 -0
- data/lib/semantic_logger/version.rb +1 -1
- data/test/appender_syslog_test.rb +50 -0
- metadata +5 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 986fd023dd3d5b61817027e25aeae6b6919f65f2
         | 
| 4 | 
            +
              data.tar.gz: 7c94accd89688c3ee66fb05c1f17eaba10183abb
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 48eeadcce9890d4d8adb53c8a76c98b259a230f8c7c0c41f3d2ae62ce94bfc850a51c7e6a143064590960aac5e0b12759ec01a396ff9bad93459ecfc81b48778
         | 
| 7 | 
            +
              data.tar.gz: ce6a05fe76874b04e2a28bfaf0a09aeb790c9fdc119744dd0b975e22286402a0c62909d67f04fe6d885ed1873397e9b31614528ea285ec696d30a69ab852bafd
         | 
    
        data/README.md
    CHANGED
    
    | @@ -5,13 +5,13 @@ Improved logging for Ruby | |
| 5 5 |  | 
| 6 6 | 
             
            * http://github.com/ClarityServices/semantic_logger
         | 
| 7 7 |  | 
| 8 | 
            -
             | 
| 8 | 
            +
            ## Note:
         | 
| 9 9 |  | 
| 10 10 | 
             
            As of SemanticLogger V2.0 the Rails logging is no longer automatically replaced
         | 
| 11 11 | 
             
            when including SemanticLogger. Include the [rails_semantic_logger](http://github.com/ClarityServices/rails_semantic_logger)
         | 
| 12 12 | 
             
            gem to replace the Rails default logger with SemanticLogger
         | 
| 13 13 |  | 
| 14 | 
            -
             | 
| 14 | 
            +
            ## Overview
         | 
| 15 15 |  | 
| 16 16 | 
             
            Semantic Logger takes logging in Ruby to a new level by adding several new
         | 
| 17 17 | 
             
            capabilities to the commonly used Logging API:
         | 
| @@ -132,7 +132,7 @@ Thread Safe | |
| 132 132 | 
             
            * Tagged logging keeps any tagging data on a per-thread basis to ensure that
         | 
| 133 133 | 
             
              tags from different threads are not inter-mingled
         | 
| 134 134 |  | 
| 135 | 
            -
             | 
| 135 | 
            +
            ## Introduction
         | 
| 136 136 |  | 
| 137 137 | 
             
            Semantic Logger is a Logger that supports logging of meta-data, along with text messages
         | 
| 138 138 | 
             
            to multiple appenders
         | 
| @@ -183,9 +183,9 @@ Since Semantic Logger can call existing Loggers, it does not force end-users | |
| 183 183 | 
             
            to have to adopt a Semantic aware adapter. Although, such adapters create
         | 
| 184 184 | 
             
            tremendous value in the problem monitoring and determination processes.
         | 
| 185 185 |  | 
| 186 | 
            -
             | 
| 186 | 
            +
            ## Logging API
         | 
| 187 187 |  | 
| 188 | 
            -
             | 
| 188 | 
            +
            ### Standard Logging methods
         | 
| 189 189 |  | 
| 190 190 | 
             
            The Semantic Logger logging API supports the existing logging interface for
         | 
| 191 191 | 
             
            the Rails and Ruby Loggers. For example:
         | 
| @@ -231,7 +231,7 @@ logger.debug("Calling Supplier", :request => 'update', :user => 'Jack') | |
| 231 231 | 
             
            logger.debug { "A total of #{result.inject(0) {|sum, i| i+sum }} were processed" }
         | 
| 232 232 | 
             
            ```
         | 
| 233 233 |  | 
| 234 | 
            -
             | 
| 234 | 
            +
            ## Exceptions
         | 
| 235 235 |  | 
| 236 236 | 
             
            The Semantic Logger adds an optional parameter to the existing log methods so that
         | 
| 237 237 | 
             
            a corresponding Exception can be logged in a standard way
         | 
| @@ -246,7 +246,7 @@ rescue Exception => exception | |
| 246 246 | 
             
            end
         | 
| 247 247 | 
             
            ```
         | 
| 248 248 |  | 
| 249 | 
            -
             | 
| 249 | 
            +
            ### Payload
         | 
| 250 250 |  | 
| 251 251 | 
             
            The Semantic Logger adds an extra parameter to the existing log methods so that
         | 
| 252 252 | 
             
            additional payload can be logged, such as a Hash or a Ruby Exception object.
         | 
| @@ -260,7 +260,7 @@ regular expressions so that a program can analyze log output. With the MongoDB | |
| 260 260 | 
             
            appender the payload is written directly to MongoDB as part of the document and
         | 
| 261 261 | 
             
            is therefore fully searchable
         | 
| 262 262 |  | 
| 263 | 
            -
             | 
| 263 | 
            +
            ### Benchmarking
         | 
| 264 264 |  | 
| 265 265 | 
             
            Another common logging requirement is to measure the time it takes to execute a block
         | 
| 266 266 | 
             
            of code based on the log level. For example:
         | 
| @@ -317,7 +317,7 @@ Parameters | |
| 317 317 | 
             
                Optional, Ruby Exception object to log along with the duration of the supplied block
         | 
| 318 318 | 
             
            ```
         | 
| 319 319 |  | 
| 320 | 
            -
             | 
| 320 | 
            +
            ### Logging levels
         | 
| 321 321 |  | 
| 322 322 | 
             
            The following logging levels are available through Semantic Logger
         | 
| 323 323 |  | 
| @@ -336,7 +336,7 @@ in the development environment for low level trace logging of methods calls etc. | |
| 336 336 | 
             
            If only the rails logger is being used, then :trace level calls will be logged
         | 
| 337 337 | 
             
            as debug calls only if the log level is set to trace
         | 
| 338 338 |  | 
| 339 | 
            -
             | 
| 339 | 
            +
            ### Changing the Class name for Log Entries
         | 
| 340 340 |  | 
| 341 341 | 
             
            When Semantic Logger is included in a Rails project it automatically replaces the
         | 
| 342 342 | 
             
            loggers for Rails, ActiveRecord::Base, ActionController::Base, and ActiveResource::Base
         | 
| @@ -375,7 +375,7 @@ This will result in the log output identifying the log entry as from the Externa | |
| 375 375 |  | 
| 376 376 | 
             
                2012-08-30 15:37:29.474 I [48308:ScriptThreadProcess: script/rails] (5.2ms) ExternalSupplier -- Calling external interface
         | 
| 377 377 |  | 
| 378 | 
            -
             | 
| 378 | 
            +
            ### Tagged Logging
         | 
| 379 379 |  | 
| 380 380 | 
             
            Semantic Logger allows any Ruby or Rails program to also include tagged logging.
         | 
| 381 381 |  | 
| @@ -393,7 +393,7 @@ logger.tagged(tracking_number) do | |
| 393 393 | 
             
            end
         | 
| 394 394 | 
             
            ```
         | 
| 395 395 |  | 
| 396 | 
            -
             | 
| 396 | 
            +
            ### Beyond Tagged Logging
         | 
| 397 397 |  | 
| 398 398 | 
             
            Blocks of code can be tagged with not only values, but can be tagged with
         | 
| 399 399 | 
             
            entire hashes of data. The additional hash of data will be merged into
         | 
| @@ -409,7 +409,7 @@ logger.with_payload(:user => 'Jack', :zip_code => 12345) do | |
| 409 409 | 
             
            end
         | 
| 410 410 | 
             
            ```
         | 
| 411 411 |  | 
| 412 | 
            -
             | 
| 412 | 
            +
            ## Standalone SemanticLogger
         | 
| 413 413 |  | 
| 414 414 | 
             
            When using SemanticLogger inside of Rails all we need to do is include the
         | 
| 415 415 | 
             
            rails_semantic_logger gem and the default Rails logger will be replaced with
         | 
| @@ -533,17 +533,34 @@ class ExternalSupplier | |
| 533 533 | 
             
            end
         | 
| 534 534 | 
             
            ```
         | 
| 535 535 |  | 
| 536 | 
            -
            ###  | 
| 536 | 
            +
            ### Logging to Syslog
         | 
| 537 | 
            +
             | 
| 538 | 
            +
            Log to a local Syslog:
         | 
| 539 | 
            +
            ```ruby
         | 
| 540 | 
            +
            require 'semantic_logger'
         | 
| 541 | 
            +
            SemanticLogger.default_level = :trace
         | 
| 542 | 
            +
            SemanticLogger.add_appender(SemanticLogger::Appender::Syslog.new)
         | 
| 543 | 
            +
            ```
         | 
| 544 | 
            +
             | 
| 545 | 
            +
            Log to a local file and to a remote Syslog server such as syslog-ng over TCP:
         | 
| 546 | 
            +
            ```ruby
         | 
| 547 | 
            +
            require 'semantic_logger'
         | 
| 548 | 
            +
            SemanticLogger.default_level = :trace
         | 
| 549 | 
            +
            SemanticLogger.add_appender('development.log')
         | 
| 550 | 
            +
            SemanticLogger.add_appender(SemanticLogger::Appender::Syslog.new(:server => 'tcp://myloghost:514'))
         | 
| 551 | 
            +
            ```
         | 
| 552 | 
            +
             | 
| 553 | 
            +
            ## Configuration
         | 
| 537 554 |  | 
| 538 555 | 
             
            The Semantic Logger follows the principle where multiple appenders can be active
         | 
| 539 556 | 
             
            at the same time. For example, this allows one to log to MongoDB and the Rails
         | 
| 540 557 | 
             
            log file at the same time.
         | 
| 541 558 |  | 
| 542 | 
            -
             | 
| 559 | 
            +
            ### Rails Configuration
         | 
| 543 560 |  | 
| 544 561 | 
             
            To automatically replace the Rails logger with Semantic Logger use the gem [rails_semantic_logger](http://github.com/ClarityServices/rails_semantic_logger)
         | 
| 545 562 |  | 
| 546 | 
            -
             | 
| 563 | 
            +
            ## Log Struct
         | 
| 547 564 |  | 
| 548 565 | 
             
            Internally all log messages are passed around in a Log Struct. In order
         | 
| 549 566 | 
             
            to write your own custom formatter or log appender it is necessary to understand
         | 
| @@ -589,7 +606,7 @@ level_index [Integer] | |
| 589 606 |  | 
| 590 607 | 
             
            * Internal use only. Index of the log level
         | 
| 591 608 |  | 
| 592 | 
            -
             | 
| 609 | 
            +
            ### Mixing Logging Levels
         | 
| 593 610 |  | 
| 594 611 | 
             
            It is sometimes useful to log a subset of the log messages to a separate file
         | 
| 595 612 | 
             
            or appender. For example, log :error and :fatal level messages to a special
         | 
| @@ -627,7 +644,7 @@ The output is as follows: | |
| 627 644 | 
             
            2013-08-02 14:15:56.735273 W [35669:70176909690580] MyClass -- This is a warning message
         | 
| 628 645 | 
             
            ```
         | 
| 629 646 |  | 
| 630 | 
            -
             | 
| 647 | 
            +
            ### Custom Formatters
         | 
| 631 648 |  | 
| 632 649 | 
             
            The formatting for each appender can be replaced with custom code. To replace the
         | 
| 633 650 | 
             
            existing formatter supply a block of code when creating the appender.
         | 
| @@ -704,21 +721,7 @@ end | |
| 704 721 | 
             
            SemanticLogger.add_appender(mongodb_appender)
         | 
| 705 722 | 
             
            ```
         | 
| 706 723 |  | 
| 707 | 
            -
             | 
| 708 | 
            -
             | 
| 709 | 
            -
            To write log entries to a Syslog logger or any other logger of your choice,
         | 
| 710 | 
            -
            that conforms the standard Ruby Logger API, Semantic Logger has an Appender to
         | 
| 711 | 
            -
            use that logger.
         | 
| 712 | 
            -
             | 
| 713 | 
            -
            For example to configure rails to also log to the Syslogger gem:
         | 
| 714 | 
            -
            ```ruby
         | 
| 715 | 
            -
            config.after_initialize do
         | 
| 716 | 
            -
              # Besides logging to the local file also log to Syslogger
         | 
| 717 | 
            -
              config.semantic_logger.appenders << SemanticLogger::Appender::Wrapper.new(Syslogger.new("yourappname"))
         | 
| 718 | 
            -
            end
         | 
| 719 | 
            -
            ```
         | 
| 720 | 
            -
             | 
| 721 | 
            -
            ### Performance
         | 
| 724 | 
            +
            ## Performance
         | 
| 722 725 |  | 
| 723 726 | 
             
            The traditional logging implementations write their log information to file in the
         | 
| 724 727 | 
             
            same thread of execution as the program itself. This means that for every log entry
         | 
| @@ -731,12 +734,12 @@ Also, since the logging is in this separate thread there is no impact to program | |
| 731 734 | 
             
            execution if we decided to add another appender.
         | 
| 732 735 | 
             
            For example, log to both a file and a MongoDB collection.
         | 
| 733 736 |  | 
| 734 | 
            -
             | 
| 737 | 
            +
            ## Log Rotation
         | 
| 735 738 |  | 
| 736 739 | 
             
            Since the log file is not re-opened with every call, when the log file needs
         | 
| 737 740 | 
             
            to be rotated, use a copy-truncate operation over deleting the file.
         | 
| 738 741 |  | 
| 739 | 
            -
             | 
| 742 | 
            +
            ## Why Semantic logging?
         | 
| 740 743 |  | 
| 741 744 | 
             
            Just as there is the initiative to add Semantic information to data on the web
         | 
| 742 745 | 
             
            so that computers can directly understand the content without having to resort
         | 
| @@ -750,7 +753,7 @@ Once the logging data is in the NOSQL data store it can be queried quickly and | |
| 750 753 | 
             
            efficiently. Some SQL data stores also allow complex data types that could be used
         | 
| 751 754 | 
             
            for storing and querying the logging data
         | 
| 752 755 |  | 
| 753 | 
            -
             | 
| 756 | 
            +
            ## Architecture & Performance
         | 
| 754 757 |  | 
| 755 758 | 
             
            In order to ensure that logging does not hinder the performance of the application
         | 
| 756 759 | 
             
            all log entries are written to thread-safe Queue. A separate thread is responsible
         | 
| @@ -766,7 +769,7 @@ terminates it will call flush on each of the appenders. | |
| 766 769 | 
             
            Calling SemanticLogger::Logger#flush will wait until all outstanding log messages
         | 
| 767 770 | 
             
            have been written and flushed to their respective appenders before returning.
         | 
| 768 771 |  | 
| 769 | 
            -
             | 
| 772 | 
            +
            ## Write your own Appender
         | 
| 770 773 |  | 
| 771 774 | 
             
            To write your own appender it should meet the following requirements:
         | 
| 772 775 |  | 
| @@ -821,12 +824,12 @@ instructions below. | |
| 821 824 | 
             
            Very Important: New appenders will not be accepted without complete working tests.
         | 
| 822 825 | 
             
            See the [MongoDB Appender Test](https://github.com/ClarityServices/semantic_logger/blob/master/test/appender_mongodb_test.rb) for an example.
         | 
| 823 826 |  | 
| 824 | 
            -
             | 
| 827 | 
            +
            ## Dependencies
         | 
| 825 828 |  | 
| 826 829 | 
             
            - Ruby MRI 1.8.7, 1.9.3 (or above) Or, JRuby 1.6.3 (or above)
         | 
| 827 830 | 
             
            - Optional: To log to MongoDB, Mongo Ruby Driver 1.5.2 or above
         | 
| 828 831 |  | 
| 829 | 
            -
             | 
| 832 | 
            +
            ## Install
         | 
| 830 833 |  | 
| 831 834 | 
             
                gem install semantic_logger
         | 
| 832 835 |  | 
| @@ -834,7 +837,7 @@ To log to MongoDB, it also needs the Ruby Mongo Driver | |
| 834 837 |  | 
| 835 838 | 
             
                gem install mongo
         | 
| 836 839 |  | 
| 837 | 
            -
             | 
| 840 | 
            +
            ## Future
         | 
| 838 841 |  | 
| 839 842 | 
             
            - Add support for a configuration file that can set log level by class name
         | 
| 840 843 | 
             
            - Configuration file to support adding appenders
         | 
| @@ -850,15 +853,20 @@ Meta | |
| 850 853 |  | 
| 851 854 | 
             
            This project uses [Semantic Versioning](http://semver.org/).
         | 
| 852 855 |  | 
| 853 | 
            -
             | 
| 856 | 
            +
            Author
         | 
| 854 857 | 
             
            -------
         | 
| 855 858 |  | 
| 856 859 | 
             
            Reid Morrison :: reidmo@gmail.com :: @reidmorrison
         | 
| 857 860 |  | 
| 861 | 
            +
            Contributors
         | 
| 862 | 
            +
            ------------
         | 
| 863 | 
            +
             | 
| 864 | 
            +
            Marc Bellingrath :: marrrc.b@gmail.com
         | 
| 865 | 
            +
             | 
| 858 866 | 
             
            License
         | 
| 859 867 | 
             
            -------
         | 
| 860 868 |  | 
| 861 | 
            -
            Copyright 2012,2013  | 
| 869 | 
            +
            Copyright 2012,2013 Reid Morrison
         | 
| 862 870 |  | 
| 863 871 | 
             
            Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 864 872 | 
             
            you may not use this file except in compliance with the License.
         | 
    
        data/lib/semantic_logger.rb
    CHANGED
    
    
| @@ -41,22 +41,33 @@ module SemanticLogger | |
| 41 41 | 
             
                  #
         | 
| 42 42 | 
             
                  def initialize(filename, level=nil, &block)
         | 
| 43 43 | 
             
                    raise "filename cannot be null when initializing the SemanticLogging::Appender::File" unless filename
         | 
| 44 | 
            -
                    @filename = filename
         | 
| 45 44 | 
             
                    @log = if filename.respond_to?(:write) and filename.respond_to?(:close)
         | 
| 46 45 | 
             
                      filename
         | 
| 47 46 | 
             
                    else
         | 
| 48 | 
            -
                      @ | 
| 49 | 
            -
                       | 
| 50 | 
            -
                      # Allows multiple processes to write to the same log file simultaneously
         | 
| 51 | 
            -
                      @log.sync = true
         | 
| 52 | 
            -
                      @log.set_encoding(Encoding::BINARY) if @log.respond_to?(:set_encoding)
         | 
| 53 | 
            -
                      @log
         | 
| 47 | 
            +
                      @filename = filename
         | 
| 48 | 
            +
                      reopen
         | 
| 54 49 | 
             
                    end
         | 
| 55 50 |  | 
| 56 51 | 
             
                    # Set the log level and formatter if supplied
         | 
| 57 52 | 
             
                    super(level, &block)
         | 
| 58 53 | 
             
                  end
         | 
| 59 54 |  | 
| 55 | 
            +
                  # After forking an active process call #reopen to re-open
         | 
| 56 | 
            +
                  # open the file handles etc to resources
         | 
| 57 | 
            +
                  #
         | 
| 58 | 
            +
                  # Note: This method will only work if a String filename was supplied
         | 
| 59 | 
            +
                  #       on the initializer.
         | 
| 60 | 
            +
                  def reopen
         | 
| 61 | 
            +
                    return unless @filename
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                    @log = open(@filename, (::File::WRONLY | ::File::APPEND | ::File::CREAT))
         | 
| 64 | 
            +
                    # Force all log entries to write immediately without buffering
         | 
| 65 | 
            +
                    # Allows multiple processes to write to the same log file simultaneously
         | 
| 66 | 
            +
                    @log.sync = true
         | 
| 67 | 
            +
                    @log.set_encoding(Encoding::BINARY) if @log.respond_to?(:set_encoding)
         | 
| 68 | 
            +
                    @log
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
             | 
| 60 71 | 
             
                  # Pass log calls to the underlying Rails, log4j or Ruby logger
         | 
| 61 72 | 
             
                  #  trace entries are mapped to debug since :trace is not supported by the
         | 
| 62 73 | 
             
                  #  Ruby or Rails Loggers
         | 
| @@ -0,0 +1,249 @@ | |
| 1 | 
            +
            # syslog appender for SemanticLogger - Supports local and remote syslog (over TCP or UDP)
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # Example 1
         | 
| 4 | 
            +
            # Log to the local syslog.
         | 
| 5 | 
            +
            #
         | 
| 6 | 
            +
            # require 'semantic_logger'
         | 
| 7 | 
            +
            # SemanticLogger.default_level = :trace
         | 
| 8 | 
            +
            #
         | 
| 9 | 
            +
            # syslog_appender = SemanticLogger::Appender::Syslog.new
         | 
| 10 | 
            +
            # SemanticLogger.add_appender(syslog_appender)
         | 
| 11 | 
            +
            #
         | 
| 12 | 
            +
            # logger = SemanticLogger['SyslogAppenderExample']
         | 
| 13 | 
            +
            # logger.info  "Info Hello! - This message should appear in the local syslog!"
         | 
| 14 | 
            +
            #
         | 
| 15 | 
            +
            #
         | 
| 16 | 
            +
            # Example 2
         | 
| 17 | 
            +
            # Send to a remote syslog appender - myloghost - over TCP on port 514.
         | 
| 18 | 
            +
            # Tested with syslog-ng as part of an ELSA installation.
         | 
| 19 | 
            +
            # https://code.google.com/p/enterprise-log-search-and-archive/
         | 
| 20 | 
            +
            #
         | 
| 21 | 
            +
            # require 'semantic_logger'
         | 
| 22 | 
            +
            # # Only log warn and above messages to the remote syslog.
         | 
| 23 | 
            +
            # syslog_appender = SemanticLogger::Appender::Syslog.new(level: :warn, server: 'tcp://myloghost:514')
         | 
| 24 | 
            +
            # SemanticLogger.add_appender(syslog_appender)
         | 
| 25 | 
            +
            #
         | 
| 26 | 
            +
            # logger = SemanticLogger['SyslogAppenderExample']
         | 
| 27 | 
            +
            # logger.info  "Info Hello!   - The log level is too low and will not be logged."
         | 
| 28 | 
            +
            # logger.error "Error! Error! - This message should appear in the remote syslog!"
         | 
| 29 | 
            +
            #
         | 
| 30 | 
            +
            require 'syslog'
         | 
| 31 | 
            +
            require 'uri'
         | 
| 32 | 
            +
            require 'socket'
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            module SemanticLogger
         | 
| 35 | 
            +
              module Appender
         | 
| 36 | 
            +
                class Syslog < SemanticLogger::Appender::Base
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  attr_reader :remote_syslog, :server, :host, :port, :protocol, :facility, :local_hostname
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  # Default mapping of ruby log levels to syslog log levels
         | 
| 41 | 
            +
                  #
         | 
| 42 | 
            +
                  # ::Syslog::LOG_EMERG   - "System is unusable"
         | 
| 43 | 
            +
                  # ::Syslog::LOG_ALERT   - "Action needs to be taken immediately"
         | 
| 44 | 
            +
                  # ::Syslog::LOG_CRIT    - "A critical condition has occurred"
         | 
| 45 | 
            +
                  # ::Syslog::LOG_ERR     - "An error occurred"
         | 
| 46 | 
            +
                  # ::Syslog::LOG_WARNING - "Warning of a possible problem"
         | 
| 47 | 
            +
                  # ::Syslog::LOG_NOTICE  - "A normal but significant condition occurred"
         | 
| 48 | 
            +
                  # ::Syslog::LOG_INFO    - "Informational message"
         | 
| 49 | 
            +
                  # ::Syslog::LOG_DEBUG   - "Debugging information"
         | 
| 50 | 
            +
                  DEFAULT_LEVEL_MAP = {
         | 
| 51 | 
            +
                      :fatal   => ::Syslog::LOG_CRIT,
         | 
| 52 | 
            +
                      :error   => ::Syslog::LOG_ERR,
         | 
| 53 | 
            +
                      :warn    => ::Syslog::LOG_WARNING,
         | 
| 54 | 
            +
                      :info    => ::Syslog::LOG_NOTICE,
         | 
| 55 | 
            +
                      :debug   => ::Syslog::LOG_INFO,
         | 
| 56 | 
            +
                      :trace   => ::Syslog::LOG_DEBUG
         | 
| 57 | 
            +
                  }
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  # For more information on the Syslog constants used below see http://ruby-doc.org/stdlib-2.0.0/libdoc/syslog/rdoc/Syslog.html
         | 
| 60 | 
            +
                  # Parameters
         | 
| 61 | 
            +
                  #
         | 
| 62 | 
            +
                  #   :ident [String]
         | 
| 63 | 
            +
                  #     Identity of the program
         | 
| 64 | 
            +
                  #     Default: 'ruby'
         | 
| 65 | 
            +
                  #
         | 
| 66 | 
            +
                  #   :options [Integer]
         | 
| 67 | 
            +
                  #     Default: ::Syslog::LOG_PID | ::Syslog::LOG_CONS
         | 
| 68 | 
            +
                  #     Any of the following (options can be logically OR'd together)
         | 
| 69 | 
            +
                  #       ::Syslog::LOG_CONS
         | 
| 70 | 
            +
                  #       ::Syslog::LOG_NDELAY
         | 
| 71 | 
            +
                  #       ::Syslog::LOG_NOWAIT
         | 
| 72 | 
            +
                  #       ::Syslog::LOG_ODELAY
         | 
| 73 | 
            +
                  #       ::Syslog::LOG_PERROR
         | 
| 74 | 
            +
                  #       ::Syslog::LOG_PID
         | 
| 75 | 
            +
                  #
         | 
| 76 | 
            +
                  #   :facility [Integer]
         | 
| 77 | 
            +
                  #     Default: ::Syslog::LOG_USER
         | 
| 78 | 
            +
                  #     Type of program (can be logically OR'd together)
         | 
| 79 | 
            +
                  #       ::Syslog::LOG_AUTH
         | 
| 80 | 
            +
                  #       ::Syslog::LOG_AUTHPRIV
         | 
| 81 | 
            +
                  #       ::Syslog::LOG_CONSOLE
         | 
| 82 | 
            +
                  #       ::Syslog::LOG_CRON
         | 
| 83 | 
            +
                  #       ::Syslog::LOG_DAEMON
         | 
| 84 | 
            +
                  #       ::Syslog::LOG_FTP
         | 
| 85 | 
            +
                  #       ::Syslog::LOG_KERN
         | 
| 86 | 
            +
                  #       ::Syslog::LOG_LRP
         | 
| 87 | 
            +
                  #       ::Syslog::LOG_MAIL
         | 
| 88 | 
            +
                  #       ::Syslog::LOG_NEWS
         | 
| 89 | 
            +
                  #       ::Syslog::LOG_NTP
         | 
| 90 | 
            +
                  #       ::Syslog::LOG_SECURITY
         | 
| 91 | 
            +
                  #       ::Syslog::LOG_SYSLOG
         | 
| 92 | 
            +
                  #       ::Syslog::LOG_USER
         | 
| 93 | 
            +
                  #       ::Syslog::LOG_UUCP
         | 
| 94 | 
            +
                  #       ::Syslog::LOG_LOCAL0
         | 
| 95 | 
            +
                  #       ::Syslog::LOG_LOCAL1
         | 
| 96 | 
            +
                  #       ::Syslog::LOG_LOCAL2
         | 
| 97 | 
            +
                  #       ::Syslog::LOG_LOCAL3
         | 
| 98 | 
            +
                  #       ::Syslog::LOG_LOCAL4
         | 
| 99 | 
            +
                  #       ::Syslog::LOG_LOCAL5
         | 
| 100 | 
            +
                  #       ::Syslog::LOG_LOCAL6
         | 
| 101 | 
            +
                  #       ::Syslog::LOG_LOCAL7
         | 
| 102 | 
            +
                  #
         | 
| 103 | 
            +
                  #   :level [Symbol]
         | 
| 104 | 
            +
                  #     Default: SemanticLogger's log level.
         | 
| 105 | 
            +
                  #     The minimum level at which this appender will write logs. Any log messages below this level will be ignored.
         | 
| 106 | 
            +
                  #
         | 
| 107 | 
            +
                  #   :level_map [Hash]
         | 
| 108 | 
            +
                  #     Supply a custom map of SemanticLogger levels to syslog levels.
         | 
| 109 | 
            +
                  #     For example, passing in { :warn => ::Syslog::LOG_NOTICE }
         | 
| 110 | 
            +
                  #       would result in a log mapping that matches the default level map,
         | 
| 111 | 
            +
                  #       except for :warn, which ends up with a LOG_NOTICE level instead of a
         | 
| 112 | 
            +
                  #       LOG_WARNING one.
         | 
| 113 | 
            +
                  #     Without overriding any parameters, the level map will be
         | 
| 114 | 
            +
                  #       LEVEL_MAP = {
         | 
| 115 | 
            +
                  #         :fatal   => ::Syslog::LOG_CRIT,
         | 
| 116 | 
            +
                  #         :error   => ::Syslog::LOG_ERR,
         | 
| 117 | 
            +
                  #         :warn    => ::Syslog::LOG_WARNING,
         | 
| 118 | 
            +
                  #         :info    => ::Syslog::LOG_NOTICE,
         | 
| 119 | 
            +
                  #         :debug   => ::Syslog::LOG_INFO,
         | 
| 120 | 
            +
                  #         :trace   => ::Syslog::LOG_DEBUG
         | 
| 121 | 
            +
                  #       }
         | 
| 122 | 
            +
                  #
         | 
| 123 | 
            +
                  #   :local_hostname [String]
         | 
| 124 | 
            +
                  #     Default: Socket.gethostname || `hostname`.strip
         | 
| 125 | 
            +
                  #     Hostname to provide to the remote syslog.
         | 
| 126 | 
            +
                  #
         | 
| 127 | 
            +
                  #   :server [String]
         | 
| 128 | 
            +
                  #     Default: 'syslog://localhost'
         | 
| 129 | 
            +
                  #     For writing logs to a remote syslog server
         | 
| 130 | 
            +
                  #     URI of server: protocol://host:port
         | 
| 131 | 
            +
                  #     Uses port 514 by default for TCP and UDP.
         | 
| 132 | 
            +
                  #     local syslog example:          'syslog://localhost'
         | 
| 133 | 
            +
                  #     TCP example with default port: 'tcp://logger'
         | 
| 134 | 
            +
                  #     TCP example with custom port:  'tcp://logger:8514'
         | 
| 135 | 
            +
                  #     UDP example with default port: 'udp://logger'
         | 
| 136 | 
            +
                  #     UDP example with custom port:  'udp://logger:8514'
         | 
| 137 | 
            +
                  #     When using the :syslog protocol, logs will always be sent to the localhost syslog
         | 
| 138 | 
            +
                  #
         | 
| 139 | 
            +
                  #   :tcp_client [Hash]
         | 
| 140 | 
            +
                  #     Default: {}
         | 
| 141 | 
            +
                  #     Only used with the TCP protocol.
         | 
| 142 | 
            +
                  #     Specify custom parameters to pass into ResilientSocket.TCPClient.new
         | 
| 143 | 
            +
                  #     For a list of options see the resilient_socket documentation:
         | 
| 144 | 
            +
                  #       https://github.com/reidmorrison/resilient_socket/blob/master/lib/resilient_socket/tcp_client.rb
         | 
| 145 | 
            +
                  def initialize(params = {}, &block)
         | 
| 146 | 
            +
                    params = params.dup
         | 
| 147 | 
            +
                    @ident = params.delete(:ident) || 'ruby'
         | 
| 148 | 
            +
                    options = params.delete(:options) || (::Syslog::LOG_PID | ::Syslog::LOG_CONS)
         | 
| 149 | 
            +
                    @facility = params.delete(:facility) || ::Syslog::LOG_USER
         | 
| 150 | 
            +
                    level = params.delete(:level)
         | 
| 151 | 
            +
                    level_map = params.delete(:level_map)
         | 
| 152 | 
            +
                    @level_map = DEFAULT_LEVEL_MAP.dup
         | 
| 153 | 
            +
                    @level_map.update(level_map) if level_map
         | 
| 154 | 
            +
                    @server = params.delete(:server) || 'syslog://localhost'
         | 
| 155 | 
            +
                    uri = URI(@server)
         | 
| 156 | 
            +
                    @host = uri.host || 'localhost'
         | 
| 157 | 
            +
                    @protocol = (uri.scheme || :syslog).to_sym
         | 
| 158 | 
            +
                    raise "Unknown protocol #{@protocol}!" unless [:syslog, :tcp, :udp].include?(@protocol)
         | 
| 159 | 
            +
                    @host = 'localhost' if @protocol == :syslog
         | 
| 160 | 
            +
                    @port = URI(@server).port || 514
         | 
| 161 | 
            +
                    @local_hostname = params.delete(:local_hostname) || Socket.gethostname || `hostname`.strip
         | 
| 162 | 
            +
                    tcp_client_options = params.delete(:tcp_client)
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                    # Warn about any unknown configuration options.
         | 
| 165 | 
            +
                    params.each_pair { |key,val| SemanticLogger::Logger.logger.warn "Ignoring unknown configuration option: #{key.inspect} => #{val.inspect}" }
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                    # The syslog_protocol gem is required when logging over TCP or UDP.
         | 
| 168 | 
            +
                    if [:tcp, :udp].include?(@protocol)
         | 
| 169 | 
            +
                      begin
         | 
| 170 | 
            +
                        require 'syslog_protocol'
         | 
| 171 | 
            +
                      rescue LoadError
         | 
| 172 | 
            +
                        raise 'Missing gem: syslog_protocol. This gem is required when logging over TCP or UDP. To fix this error: gem install syslog_protocol'
         | 
| 173 | 
            +
                      end
         | 
| 174 | 
            +
                    end
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                    case @protocol
         | 
| 177 | 
            +
                      when :syslog
         | 
| 178 | 
            +
                        ::Syslog.open(@ident, options, @facility)
         | 
| 179 | 
            +
                      when :tcp
         | 
| 180 | 
            +
                        # The resilient_socket gem is required when logging over TCP.
         | 
| 181 | 
            +
                        begin
         | 
| 182 | 
            +
                          require 'resilient_socket'
         | 
| 183 | 
            +
                        rescue LoadError
         | 
| 184 | 
            +
                          raise 'Missing gem: resilient_socket. This gem is required when logging over TCP. To fix this error: gem install resilient_socket'
         | 
| 185 | 
            +
                        end
         | 
| 186 | 
            +
                        options = tcp_client_options || {}
         | 
| 187 | 
            +
                        options[:server] = "#{@host}:#{@port}"
         | 
| 188 | 
            +
                        @remote_syslog = ResilientSocket::TCPClient.new(options)
         | 
| 189 | 
            +
                        # Use the local logger for @remote_syslog so errors with the remote logger can be recorded locally.
         | 
| 190 | 
            +
                        @remote_syslog.logger = SemanticLogger::Logger.logger
         | 
| 191 | 
            +
                      when :udp
         | 
| 192 | 
            +
                        @remote_syslog = UDPSocket.new
         | 
| 193 | 
            +
                      else
         | 
| 194 | 
            +
                        raise "Unsupported protocol: #{protocol}"
         | 
| 195 | 
            +
                    end
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                    super(level, &block)
         | 
| 198 | 
            +
                  end
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                  # Write the log using the specified protocol and host.
         | 
| 201 | 
            +
                  def log(log)
         | 
| 202 | 
            +
                    if level_index <= (log.level_index || 0)
         | 
| 203 | 
            +
                      case @protocol
         | 
| 204 | 
            +
                        when :syslog
         | 
| 205 | 
            +
                          ::Syslog.log @level_map[log.level], formatter.call(log)
         | 
| 206 | 
            +
                        when :tcp
         | 
| 207 | 
            +
                          @remote_syslog.retry_on_connection_failure { @remote_syslog.write("#{syslog_packet_formatter(log)}\r\n") }
         | 
| 208 | 
            +
                        when :udp
         | 
| 209 | 
            +
                          @remote_syslog.send syslog_packet_formatter(log), 0, @host, @port
         | 
| 210 | 
            +
                        else
         | 
| 211 | 
            +
                          raise "Unsupported protocol: #{protocol}"
         | 
| 212 | 
            +
                      end
         | 
| 213 | 
            +
                    end
         | 
| 214 | 
            +
                  end
         | 
| 215 | 
            +
             | 
| 216 | 
            +
                  # Flush is called by the semantic_logger during shutdown.
         | 
| 217 | 
            +
                  def flush
         | 
| 218 | 
            +
                    # TODO Add flush for :tcp.
         | 
| 219 | 
            +
                  end
         | 
| 220 | 
            +
             | 
| 221 | 
            +
                  # Custom log formatter for syslog
         | 
| 222 | 
            +
                  def default_formatter
         | 
| 223 | 
            +
                    Proc.new do |log|
         | 
| 224 | 
            +
                      tags = log.tags.collect { |tag| "[#{tag}]" }.join(" ") + " " if log.tags && (log.tags.size > 0)
         | 
| 225 | 
            +
             | 
| 226 | 
            +
                      message = log.message.to_s
         | 
| 227 | 
            +
                      message << " -- " << log.payload.inspect if log.payload
         | 
| 228 | 
            +
                      message << " -- " << "#{log.exception.class}: #{log.exception.message}\n#{(log.exception.backtrace || []).join("\n")}" if log.exception
         | 
| 229 | 
            +
             | 
| 230 | 
            +
                      duration_str = log.duration ? "(#{'%.1f' % log.duration}ms) " : ''
         | 
| 231 | 
            +
             | 
| 232 | 
            +
                      "#{log.level.to_s[0..0].upcase} [#{$$}:#{log.thread_name}] #{tags}#{duration_str}#{log.name} -- #{message}"
         | 
| 233 | 
            +
                    end
         | 
| 234 | 
            +
                  end
         | 
| 235 | 
            +
             | 
| 236 | 
            +
                  # Format the syslog packet so it can be sent over TCP or UDP
         | 
| 237 | 
            +
                  def syslog_packet_formatter(log)
         | 
| 238 | 
            +
                    packet = SyslogProtocol::Packet.new
         | 
| 239 | 
            +
                    packet.hostname = @local_hostname
         | 
| 240 | 
            +
                    packet.facility = @facility
         | 
| 241 | 
            +
                    packet.severity =  @level_map[log.level]
         | 
| 242 | 
            +
                    packet.tag = @ident
         | 
| 243 | 
            +
                    packet.content = default_formatter.call(log)
         | 
| 244 | 
            +
                    packet.to_s
         | 
| 245 | 
            +
                  end
         | 
| 246 | 
            +
             | 
| 247 | 
            +
                end
         | 
| 248 | 
            +
              end
         | 
| 249 | 
            +
            end
         | 
| @@ -122,6 +122,14 @@ module SemanticLogger | |
| 122 122 | 
             
                SemanticLogger::Logger.flush
         | 
| 123 123 | 
             
              end
         | 
| 124 124 |  | 
| 125 | 
            +
              # After forking an active process call SemanticLogger.reopen to re-open
         | 
| 126 | 
            +
              # any open file handles etc to resources
         | 
| 127 | 
            +
              #
         | 
| 128 | 
            +
              # Note: Only appenders that implement the reopen method will be called
         | 
| 129 | 
            +
              def self.reopen
         | 
| 130 | 
            +
                @@appenders.each {|appender| appender.reopen if appender.respond_to?(:reopen)}
         | 
| 131 | 
            +
              end
         | 
| 132 | 
            +
             | 
| 125 133 | 
             
              ############################################################################
         | 
| 126 134 | 
             
              protected
         | 
| 127 135 |  | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            # Allow test to be run in-place without requiring a gem install
         | 
| 2 | 
            +
            $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require 'rubygems'
         | 
| 5 | 
            +
            require 'test/unit'
         | 
| 6 | 
            +
            require 'shoulda'
         | 
| 7 | 
            +
            require 'mocha/setup'
         | 
| 8 | 
            +
            require 'semantic_logger'
         | 
| 9 | 
            +
            require 'socket'
         | 
| 10 | 
            +
            require 'resilient_socket'
         | 
| 11 | 
            +
            require 'syslog_protocol'
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            # Unit Test for SemanticLogger::Appender::Syslog
         | 
| 14 | 
            +
            #
         | 
| 15 | 
            +
            class AppenderSyslogTest < Test::Unit::TestCase
         | 
| 16 | 
            +
              context SemanticLogger::Appender::Syslog do
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                should 'handle local syslog' do
         | 
| 19 | 
            +
                  ::Syslog.expects(:open).once
         | 
| 20 | 
            +
                  ::Syslog.expects(:log).once
         | 
| 21 | 
            +
                  syslog_appender = SemanticLogger::Appender::Syslog.new
         | 
| 22 | 
            +
                  syslog_appender.debug 'AppenderSyslogTest log message'
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                should 'handle remote syslog over TCP' do
         | 
| 26 | 
            +
                  ::ResilientSocket::TCPClient.any_instance.stubs('closed?').returns(false)
         | 
| 27 | 
            +
                  ::ResilientSocket::TCPClient.any_instance.stubs('connect')
         | 
| 28 | 
            +
                  ::ResilientSocket::TCPClient.any_instance.expects(:write).with{ |message| message =~ /<70>(.*?)SemanticLogger::Appender::Syslog -- AppenderSyslogTest log message\r\n/ }
         | 
| 29 | 
            +
                  syslog_appender = SemanticLogger::Appender::Syslog.new(:server => 'tcp://localhost:88888')
         | 
| 30 | 
            +
                  syslog_appender.debug 'AppenderSyslogTest log message'
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                should 'handle remote syslog over UDP' do
         | 
| 34 | 
            +
                  ::UDPSocket.any_instance.expects(:send).with{ |*params| params[0] =~ /<70>(.*?)SemanticLogger::Appender::Syslog -- AppenderSyslogTest log message/ }
         | 
| 35 | 
            +
                  syslog_appender = SemanticLogger::Appender::Syslog.new(:server => 'udp://localhost:88888')
         | 
| 36 | 
            +
                  syslog_appender.debug 'AppenderSyslogTest log message'
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                # Should be able to log each level.
         | 
| 40 | 
            +
                SemanticLogger::LEVELS.each do |level|
         | 
| 41 | 
            +
                  should "log #{level} information" do
         | 
| 42 | 
            +
                    ::Syslog.expects(:open).once
         | 
| 43 | 
            +
                    ::Syslog.expects(:log).once
         | 
| 44 | 
            +
                    syslog_appender = SemanticLogger::Appender::Syslog.new
         | 
| 45 | 
            +
                    syslog_appender.send(level, 'AppenderSyslogTest #{level.to_s} message')
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: semantic_logger
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 4 | 
            +
              version: 2.4.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Reid Morrison
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2013- | 
| 11 | 
            +
            date: 2013-10-25 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: sync_attr
         | 
| @@ -49,6 +49,7 @@ files: | |
| 49 49 | 
             
            - lib/semantic_logger/appender/base.rb
         | 
| 50 50 | 
             
            - lib/semantic_logger/appender/file.rb
         | 
| 51 51 | 
             
            - lib/semantic_logger/appender/mongodb.rb
         | 
| 52 | 
            +
            - lib/semantic_logger/appender/syslog.rb
         | 
| 52 53 | 
             
            - lib/semantic_logger/appender/wrapper.rb
         | 
| 53 54 | 
             
            - lib/semantic_logger/base.rb
         | 
| 54 55 | 
             
            - lib/semantic_logger/loggable.rb
         | 
| @@ -61,6 +62,7 @@ files: | |
| 61 62 | 
             
            - README.md
         | 
| 62 63 | 
             
            - test/appender_file_test.rb
         | 
| 63 64 | 
             
            - test/appender_mongodb_test.rb
         | 
| 65 | 
            +
            - test/appender_syslog_test.rb
         | 
| 64 66 | 
             
            - test/appender_wrapper_test.rb
         | 
| 65 67 | 
             
            - test/loggable_test.rb
         | 
| 66 68 | 
             
            - test/logger_test.rb
         | 
| @@ -92,6 +94,7 @@ summary: Improved logging for Ruby | |
| 92 94 | 
             
            test_files:
         | 
| 93 95 | 
             
            - test/appender_file_test.rb
         | 
| 94 96 | 
             
            - test/appender_mongodb_test.rb
         | 
| 97 | 
            +
            - test/appender_syslog_test.rb
         | 
| 95 98 | 
             
            - test/appender_wrapper_test.rb
         | 
| 96 99 | 
             
            - test/loggable_test.rb
         | 
| 97 100 | 
             
            - test/logger_test.rb
         |