ezmetrics 1.1.0 → 1.1.1
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 +20 -22
- data/lib/ezmetrics.rb +19 -24
- data/lib/ezmetrics/benchmark.rb +2 -2
- metadata +1 -1
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 518d9350ed026801311bdc695857fdd057856f6b7fe40715bf8072c990e8e5b8
         | 
| 4 | 
            +
              data.tar.gz: 7d36fbd3e63994789ce8ac04212fb44c30041fd33f7173fbfdf1a6257beea99a
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 42e990916d474ed52f08330bd7210b4c6f464a0199354cfc1fe3710817b9d57790d445d0d1f88c8fccd6daeb627638a80dd8b578c685544f6a4f9c7765522a5f
         | 
| 7 | 
            +
              data.tar.gz: 5b49eec021acaef39af2c9401681fa85f02d368f36231a60a64faf595e5b0c1432ce07a67fb86ce9c8b3041835fd4480da86ea5d91f7ca0939ef5b40592e6a49
         | 
    
        data/README.md
    CHANGED
    
    | @@ -31,22 +31,20 @@ You can change the timeframe according to your needs and save the metrics by cal | |
| 31 31 | 
             
              EZmetrics.new.log(duration: 100.5, views: 40.7, db: 59.8, queries: 4, status: 200)
         | 
| 32 32 | 
             
            ```
         | 
| 33 33 |  | 
| 34 | 
            -
            or
         | 
| 35 | 
            -
             | 
| 36 34 | 
             
            ```ruby
         | 
| 37 35 | 
             
              # Store the metrics for 10 minutes
         | 
| 38 36 | 
             
              EZmetrics.new(10.minutes).log(duration: 100.5, views: 40.7, db: 59.8, queries: 4, status: 200)
         | 
| 39 37 | 
             
            ```
         | 
| 40 38 |  | 
| 41 | 
            -
             | 
| 39 | 
            +
            ---
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            For displaying metrics you need to call `show` method:
         | 
| 42 42 |  | 
| 43 43 | 
             
            ```ruby
         | 
| 44 44 | 
             
              # Aggregate and show metrics for last 60 seconds (default behaviour)
         | 
| 45 45 | 
             
              EZmetrics.new.show
         | 
| 46 46 | 
             
            ```
         | 
| 47 47 |  | 
| 48 | 
            -
            or
         | 
| 49 | 
            -
             | 
| 50 48 | 
             
            ```ruby
         | 
| 51 49 | 
             
              # Aggregate and show metrics for last 10 minutes
         | 
| 52 50 | 
             
              EZmetrics.new(10.minutes).show
         | 
| @@ -121,11 +119,11 @@ This will return a hash with the following structure: | |
| 121 119 | 
             
            }
         | 
| 122 120 | 
             
            ```
         | 
| 123 121 |  | 
| 124 | 
            -
            ###  | 
| 122 | 
            +
            ### Aggregation options
         | 
| 125 123 |  | 
| 126 | 
            -
            The  | 
| 124 | 
            +
            The aggregation can be easily configured by specifying aggregation options as in the following examples:
         | 
| 127 125 |  | 
| 128 | 
            -
            1. Single
         | 
| 126 | 
            +
            **1. Single**
         | 
| 129 127 |  | 
| 130 128 | 
             
            ```ruby
         | 
| 131 129 | 
             
            EZmetrics.new.show(duration: :max)
         | 
| @@ -139,7 +137,9 @@ EZmetrics.new.show(duration: :max) | |
| 139 137 | 
             
            }
         | 
| 140 138 | 
             
            ```
         | 
| 141 139 |  | 
| 142 | 
            -
             | 
| 140 | 
            +
            ---
         | 
| 141 | 
            +
             | 
| 142 | 
            +
            **2. Multiple**
         | 
| 143 143 |  | 
| 144 144 | 
             
            ```ruby
         | 
| 145 145 | 
             
            EZmetrics.new.show(queries: [:max, :avg])
         | 
| @@ -154,7 +154,9 @@ EZmetrics.new.show(queries: [:max, :avg]) | |
| 154 154 | 
             
            }
         | 
| 155 155 | 
             
            ```
         | 
| 156 156 |  | 
| 157 | 
            -
             | 
| 157 | 
            +
            ---
         | 
| 158 | 
            +
             | 
| 159 | 
            +
            **3. Requests**
         | 
| 158 160 |  | 
| 159 161 | 
             
            ```ruby
         | 
| 160 162 | 
             
            EZmetrics.new.show(requests: true)
         | 
| @@ -174,7 +176,9 @@ EZmetrics.new.show(requests: true) | |
| 174 176 | 
             
            }
         | 
| 175 177 | 
             
            ```
         | 
| 176 178 |  | 
| 177 | 
            -
             | 
| 179 | 
            +
            ---
         | 
| 180 | 
            +
             | 
| 181 | 
            +
            **4. Combined**
         | 
| 178 182 |  | 
| 179 183 | 
             
            ```ruby
         | 
| 180 184 | 
             
            EZmetrics.new.show(views: :avg, :db: [:avg, :max], requests: true)
         | 
| @@ -203,13 +207,7 @@ EZmetrics.new.show(views: :avg, :db: [:avg, :max], requests: true) | |
| 203 207 |  | 
| 204 208 | 
             
            ### Performance
         | 
| 205 209 |  | 
| 206 | 
            -
            The  | 
| 207 | 
            -
             | 
| 208 | 
            -
            - [`get`](https://redis.io/commands/get)
         | 
| 209 | 
            -
            - [`mget`](https://redis.io/commands/mget)
         | 
| 210 | 
            -
            - [`setex`](https://redis.io/commands/setex)
         | 
| 211 | 
            -
             | 
| 212 | 
            -
            which are extremely fast.
         | 
| 210 | 
            +
            The aggregation speed relies on the performance of **Redis** (data storage) and **Oj** (json serialization/parsing).
         | 
| 213 211 |  | 
| 214 212 | 
             
            You can check the **aggregation** time by running:
         | 
| 215 213 |  | 
| @@ -222,7 +220,7 @@ The result of running this benchmark on a _2017 Macbook Pro 2.9 GHz Intel Core i | |
| 222 220 | 
             
            | Interval | Duration (seconds) |
         | 
| 223 221 | 
             
            | :------: | :----------------: |
         | 
| 224 222 | 
             
            | 1 minute |        0.0         |
         | 
| 225 | 
            -
            |  1 hour  |        0. | 
| 226 | 
            -
            | 12 hours |        0. | 
| 227 | 
            -
            | 24 hours |        1. | 
| 228 | 
            -
            | 48 hours |         | 
| 223 | 
            +
            |  1 hour  |        0.04        |
         | 
| 224 | 
            +
            | 12 hours |        0.49        |
         | 
| 225 | 
            +
            | 24 hours |        1.51        |
         | 
| 226 | 
            +
            | 48 hours |        3.48        |
         | 
    
        data/lib/ezmetrics.rb
    CHANGED
    
    | @@ -9,7 +9,6 @@ class EZmetrics | |
| 9 9 | 
             
              def initialize(interval_seconds=60)
         | 
| 10 10 | 
             
                @interval_seconds = interval_seconds.to_i
         | 
| 11 11 | 
             
                @redis            = Redis.new
         | 
| 12 | 
            -
                @storage_key      = "ez-metrics"
         | 
| 13 12 | 
             
              end
         | 
| 14 13 |  | 
| 15 14 | 
             
              def log(payload={duration: 0.0, views: 0.0, db: 0.0, queries: 0, status: 200})
         | 
| @@ -23,7 +22,7 @@ class EZmetrics | |
| 23 22 |  | 
| 24 23 | 
             
                this_second          = Time.now.to_i
         | 
| 25 24 | 
             
                status_group         = "#{payload[:status].to_s[0]}xx"
         | 
| 26 | 
            -
                @this_second_metrics = redis.get( | 
| 25 | 
            +
                @this_second_metrics = redis.get(this_second)
         | 
| 27 26 |  | 
| 28 27 | 
             
                if this_second_metrics
         | 
| 29 28 | 
             
                  @this_second_metrics = Oj.load(this_second_metrics)
         | 
| @@ -51,7 +50,7 @@ class EZmetrics | |
| 51 50 | 
             
                  this_second_metrics["statuses"][status_group] = 1
         | 
| 52 51 | 
             
                end
         | 
| 53 52 |  | 
| 54 | 
            -
                redis.setex( | 
| 53 | 
            +
                redis.setex(this_second, interval_seconds, Oj.dump(this_second_metrics))
         | 
| 55 54 | 
             
                true
         | 
| 56 55 | 
             
              rescue => error
         | 
| 57 56 | 
             
                formatted_error(error)
         | 
| @@ -60,12 +59,12 @@ class EZmetrics | |
| 60 59 | 
             
              def show(options=nil)
         | 
| 61 60 | 
             
                @options          = options || default_options
         | 
| 62 61 | 
             
                interval_start    = Time.now.to_i - interval_seconds
         | 
| 63 | 
            -
                interval_keys     = (interval_start..Time.now.to_i).to_a | 
| 62 | 
            +
                interval_keys     = (interval_start..Time.now.to_i).to_a
         | 
| 64 63 | 
             
                @interval_metrics = redis.mget(interval_keys).compact.map { |hash| Oj.load(hash) }
         | 
| 65 64 |  | 
| 66 65 | 
             
                return {} unless interval_metrics.any?
         | 
| 67 66 |  | 
| 68 | 
            -
                @requests = interval_metrics. | 
| 67 | 
            +
                @requests = interval_metrics.sum { |hash| hash["statuses"]["all"] }
         | 
| 69 68 | 
             
                build_result
         | 
| 70 69 | 
             
              rescue
         | 
| 71 70 | 
             
                {}
         | 
| @@ -79,17 +78,7 @@ class EZmetrics | |
| 79 78 | 
             
              def build_result
         | 
| 80 79 | 
             
                result = {}
         | 
| 81 80 |  | 
| 82 | 
            -
                if options[:requests]
         | 
| 83 | 
            -
                  result[:requests] = {
         | 
| 84 | 
            -
                    all: requests,
         | 
| 85 | 
            -
                    grouped: {
         | 
| 86 | 
            -
                      "2xx" => count("2xx"),
         | 
| 87 | 
            -
                      "3xx" => count("3xx"),
         | 
| 88 | 
            -
                      "4xx" => count("4xx"),
         | 
| 89 | 
            -
                      "5xx" => count("5xx")
         | 
| 90 | 
            -
                    }
         | 
| 91 | 
            -
                  }
         | 
| 92 | 
            -
                end
         | 
| 81 | 
            +
                result[:requests] = { all: requests, grouped: count_all_status_groups } if options[:requests]
         | 
| 93 82 |  | 
| 94 83 | 
             
                options.each do |metrics, aggregation_functions|
         | 
| 95 84 | 
             
                  next unless METRICS.include?(metrics)
         | 
| @@ -108,29 +97,35 @@ class EZmetrics | |
| 108 97 |  | 
| 109 98 | 
             
              def aggregate(metrics, aggregation_function)
         | 
| 110 99 | 
             
                return unless AGGREGATION_FUNCTIONS.include?(aggregation_function)
         | 
| 111 | 
            -
                return avg("#{metrics}_sum" | 
| 112 | 
            -
                return max("#{metrics}_max" | 
| 100 | 
            +
                return avg("#{metrics}_sum") if aggregation_function == :avg
         | 
| 101 | 
            +
                return max("#{metrics}_max") if aggregation_function == :max
         | 
| 113 102 | 
             
              end
         | 
| 114 103 |  | 
| 115 104 | 
             
              def update_sum(metrics)
         | 
| 116 | 
            -
                this_second_metrics["#{metrics}_sum"] += safe_payload[metrics | 
| 105 | 
            +
                this_second_metrics["#{metrics}_sum"] += safe_payload[metrics]
         | 
| 117 106 | 
             
              end
         | 
| 118 107 |  | 
| 119 108 | 
             
              def update_max(metrics)
         | 
| 120 | 
            -
                max_value = [safe_payload[metrics | 
| 109 | 
            +
                max_value = [safe_payload[metrics], this_second_metrics["#{metrics}_max"]].max
         | 
| 121 110 | 
             
                this_second_metrics["#{metrics}_max"] = max_value
         | 
| 122 111 | 
             
              end
         | 
| 123 112 |  | 
| 124 113 | 
             
              def avg(metrics)
         | 
| 125 | 
            -
                (interval_metrics. | 
| 114 | 
            +
                (interval_metrics.sum { |h| h[metrics] }.to_f / requests).round
         | 
| 126 115 | 
             
              end
         | 
| 127 116 |  | 
| 128 117 | 
             
              def max(metrics)
         | 
| 129 | 
            -
                interval_metrics. | 
| 118 | 
            +
                interval_metrics.max { |h| h[metrics] }[metrics].round
         | 
| 130 119 | 
             
              end
         | 
| 131 120 |  | 
| 132 | 
            -
              def  | 
| 133 | 
            -
                interval_metrics. | 
| 121 | 
            +
              def count_all_status_groups
         | 
| 122 | 
            +
                interval_metrics.inject({ "2xx" => 0, "3xx" => 0, "4xx" => 0, "5xx" => 0 }) do |result, h|
         | 
| 123 | 
            +
                  result["2xx"] += h["statuses"]["2xx"]
         | 
| 124 | 
            +
                  result["3xx"] += h["statuses"]["3xx"]
         | 
| 125 | 
            +
                  result["4xx"] += h["statuses"]["4xx"]
         | 
| 126 | 
            +
                  result["5xx"] += h["statuses"]["5xx"]
         | 
| 127 | 
            +
                  result
         | 
| 128 | 
            +
                end
         | 
| 134 129 | 
             
              end
         | 
| 135 130 |  | 
| 136 131 | 
             
              def default_options
         | 
    
        data/lib/ezmetrics/benchmark.rb
    CHANGED
    
    | @@ -52,14 +52,14 @@ class EZmetrics::Benchmark | |
| 52 52 | 
             
                      "all" => rand(40)
         | 
| 53 53 | 
             
                    }
         | 
| 54 54 | 
             
                  }
         | 
| 55 | 
            -
                  redis.setex( | 
| 55 | 
            +
                  redis.setex(second, seconds, Oj.dump(payload))
         | 
| 56 56 | 
             
                end
         | 
| 57 57 | 
             
                nil
         | 
| 58 58 | 
             
              end
         | 
| 59 59 |  | 
| 60 60 | 
             
              def cleanup_metrics
         | 
| 61 61 | 
             
                interval_start = Time.now.to_i - intervals.values.max - 100
         | 
| 62 | 
            -
                interval_keys  = (interval_start..Time.now.to_i).to_a | 
| 62 | 
            +
                interval_keys  = (interval_start..Time.now.to_i).to_a
         | 
| 63 63 | 
             
                redis.del(interval_keys)
         | 
| 64 64 | 
             
              end
         | 
| 65 65 |  |