protor 0.0.11 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 08f75ca473acd6b2205bd2bd6eeee6436d8ee131
4
- data.tar.gz: 3e4902b2fe77f54832bcb9004b77886784b89eeb
3
+ metadata.gz: 792b0db1c9b32cc19645c2c08afc39a5446b5834
4
+ data.tar.gz: f2cdf2b5eba5ec663611a0718f4c6c7fc5d7732c
5
5
  SHA512:
6
- metadata.gz: 56d4a7e9dfff42ea32ec8449372c8a583bfeb0187a150d949caa59781e2b0cd9d7c3c643e6706db8e63c33a914152cb28d7a630f35eeff679d070be3ce138f78
7
- data.tar.gz: c47557219550a752434337d210dd5a1396fd51bee68f6bb14ba54cf3a97ac39abe17cff18cc7e3af41416c9deb169f2ecd771da4af0b998aecdb8a5a10c8fcd4
6
+ metadata.gz: d551325d26dc6e8f62bd6670feb85ac1f66ef49a3a917113d014612da99770197da1f5bf6d5a6890ba046f7ec675771d3c38da50408c8d4822e6fadb769a8190
7
+ data.tar.gz: fd9e321c2650a27e2b8b343972157a9f1e5dabdac4f3c32e4d04f9db3dd80c9830e9c7bdf12289d4de1643ea59191d4fd9920cacba98b7dfcf149b7dce4f08f1
data/README.md CHANGED
@@ -16,36 +16,39 @@ bundle install
16
16
  It automatically aggregate value
17
17
 
18
18
  ````ruby
19
- Protor.counter(:counter, 1, {label1: 1}) # value => 1
20
- Protor.counter(:counter, 1, {label1: 1}) # value => 2
19
+ protor.counter(:counter, 1, {label1: 1}) # value => 1
20
+ protor.counter(:counter, 1, {label1: 1}) # value => 2
21
21
  ````
22
22
  ### Gauge
23
23
  It automatically replace value
24
24
  ````ruby
25
- Protor.gauge(:gauge, 50) # value 50
26
- Protor.gauge(:gauge, 20) # value 20
25
+ protor.gauge(:gauge, 50) # value 50
26
+ protor.gauge(:gauge, 20) # value 20
27
27
  ````
28
28
 
29
29
  ### Histogram
30
30
  It save all observed values
31
31
  ````ruby
32
- Protor.histogram(:histogram, 10, {label1: 1}, [1,2,3,4]) # observed value [10]
33
- Protor.histogram(:histogram, 2, {label1: 1}, [1,2,3,4]( # observed value [10,2]
32
+ protor.histogram(:histogram, 10, {label1: 1}, [1,2,3,4]) # observed value [10]
33
+ protor.histogram(:histogram, 2, {label1: 1}, [1,2,3,4]( # observed value [10,2]
34
34
  ````
35
35
 
36
36
  ### Publish
37
37
  To publish all saved metrics to aggregator
38
38
  ````ruby
39
- Protor.publish
39
+ protor.publish
40
40
  ````
41
41
 
42
42
  ## Configuration
43
43
  To configure protor:
44
44
  ````ruby
45
- Protor.configure do |config|
46
- config.host = 'localhost' # aggregator host, default to localhost
47
- config.port = 10601 # aggregator port, default to 10601
48
- config.max_packet_size = 56607 # max udp packet buffer, default to 56607
45
+ $protor = Protor.new do |conf|
46
+ conf[:client] = :udp # valid option :udp and :logger, use :logger to print into a Logger
47
+ conf[:host] = 'localhost' # prometheus_aggregator host
48
+ conf[:port] = 10601 # prometheus_aggregator port
49
+ conf[:logger] = Rails.logger # logger to be used by protor
50
+ conf[:packet_size] = 56_607 # max udp packet buffer
51
+ conf[:formatter] = :udp # valid option only :udp, format to send
49
52
  end
50
53
  ````
51
54
 
@@ -1,50 +1,73 @@
1
1
  require 'monitor'
2
2
 
3
- require_relative 'protor/error'
4
- require_relative 'protor/configuration'
5
- require_relative 'protor/client'
3
+ require_relative 'protor/udp_formatter'
4
+ require_relative 'protor/udp_client'
5
+ require_relative 'protor/logger_client'
6
6
  require_relative 'protor/registry'
7
7
  require_relative 'protor/version'
8
8
 
9
- module Protor
10
- extend MonitorMixin
11
- end
9
+ class Protor
10
+ include MonitorMixin
12
11
 
13
- class << Protor
14
- def configuration
15
- @configuration ||= Protor::Configuration.new
16
- end
12
+ DEFAULT_CONFIG = {
13
+ client: :udp,
14
+ formatter: :udp,
15
+ host: 'localhost',
16
+ port: 10601,
17
+ packet_size: 56_607
18
+ }
19
+
20
+ attr_reader :config, :registry
17
21
 
18
- def configure
19
- yield(configuration)
22
+ def initialize(&block)
23
+ super(&block)
24
+
25
+ @config = DEFAULT_CONFIG.dup
26
+ @registry = Registry.new
27
+ yield(config) if block_given?
20
28
  end
21
29
 
22
30
  def publish
23
- synchronize do
24
- unless registry.empty?
25
- client.publish(registry)
26
- reset
27
- end
28
- end
31
+ safely{ client.publish(registry) }
32
+ logger.debug("publish") if logger
29
33
  end
30
34
 
31
35
  [:counter, :gauge, :histogram].each do |method|
32
- define_method method do |*args, &block|
33
- synchronize{ registry.public_send(method, *args, &block) }
36
+ define_method method do |*args|
37
+ safely{ registry.public_send(method, *args) }
38
+ logger.debug("#{method} #{args}") if logger
34
39
  end
35
40
  end
36
41
 
37
42
  private
38
43
 
44
+ def safely(&block)
45
+ synchronize(&block)
46
+ rescue StandardError => err
47
+ logger.error(err) if logger
48
+ raise err unless silent
49
+ end
50
+
39
51
  def client
40
- @client ||= Protor::Client.new(configuration)
52
+ @client ||=
53
+ case config[:client]
54
+ when :udp; UDPClient.new(config[:host], config[:port], formatter)
55
+ when :logger; LoggerClient.new(logger, formatter)
56
+ end
57
+ end
58
+
59
+ def formatter
60
+ @formatter ||=
61
+ case config[:formatter]
62
+ when :udp; UDPFormatter.new(config[:packet_size])
63
+ end
41
64
  end
42
65
 
43
- def registry
44
- @registry || reset
66
+ def logger
67
+ config[:logger]
45
68
  end
46
69
 
47
- def reset
48
- @registry = Protor::Registry.new(configuration)
70
+ def silent
71
+ config[:silent]
49
72
  end
50
73
  end
@@ -0,0 +1,66 @@
1
+ class Protor
2
+ class Entry
3
+ attr_reader :name, :type, :value, :labels, :additional
4
+ attr_writer :value
5
+
6
+ VALID_NAME = /^[a-zA-Z_:][a-zA-Z0-9_:]+$/
7
+ VALID_TYPE = [:c, :g, :h]
8
+ VALID_LABEL_NAME = /^[a-zA-Z_][a-zA-Z0-9_]*$/
9
+ VALID_LABEL_VALUE = /^[^;|=]+$/
10
+
11
+ def initialize(name, type, value, labels = nil, additional = nil)
12
+ @name = name.to_s
13
+ @type = type
14
+ @value = value
15
+ @labels = labels || {}
16
+ @additional = additional || []
17
+
18
+ verify
19
+ end
20
+
21
+ private
22
+
23
+ def verify
24
+ raise InvalidNameError, name unless name =~ VALID_NAME
25
+ raise InvalidTypeError, type unless VALID_TYPE.include?(type)
26
+ labels.each do |k, v|
27
+ raise InvalidLabelNameError, labels unless k =~ VALID_LABEL_NAME
28
+ raise InvalidLabelValueError, labels unless v =~ VALID_LABEL_VALUE
29
+ end
30
+ additional.each do |a|
31
+ raise InvalidAdditionalError, additional unless a.is_a?(Numeric)
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ class InvalidNameError < StandardError
38
+ def initialize(message)
39
+ super("Invalid name #{message}, please satisfy /^[a-zA-Z_:][a-zA-Z0-9_:]+$/")
40
+ end
41
+ end
42
+
43
+ class InvalidTypeError < StandardError
44
+ def initialize(message)
45
+ super("Invalid type #{message}, allowed types are [c, g, h]")
46
+ end
47
+ end
48
+
49
+ class InvalidLabelNameError < StandardError
50
+ def initialize(message)
51
+ super("Invalid label name #{message}, please satisfy /^[a-zA-Z_][a-zA-Z0-9_]*$/")
52
+ end
53
+ end
54
+
55
+ class InvalidLabelValueError < StandardError
56
+ def initialize(message)
57
+ super("Invalid label value #{message}, please satisfy /^[^;|=\s]+$/")
58
+ end
59
+ end
60
+
61
+ class InvalidAdditionalError < StandardError
62
+ def initialize(message)
63
+ super("Invalid additional {message}, additional must be numbers")
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,25 @@
1
+ class Protor
2
+ class EntryFamily
3
+ attr_reader :name, :type, :data
4
+
5
+ def initialize(name, type)
6
+ @name = name
7
+ @type = type
8
+ @data = {}
9
+ end
10
+
11
+ def []=(label, value)
12
+ data[label] = value
13
+ end
14
+
15
+ def [](label)
16
+ data[label]
17
+ end
18
+
19
+ def each
20
+ return unless block_given?
21
+
22
+ data.each_value{ |d| yield(d) }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,16 @@
1
+ class Protor
2
+ class LoggerClient
3
+ attr_reader :logger, :formatter
4
+
5
+ def initialize(logger, formatter)
6
+ @logger = logger
7
+ @formatter = formatter
8
+ end
9
+
10
+ def publish(payload)
11
+ formatter.format(payload) do |msg|
12
+ logger.info(msg)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,70 +1,84 @@
1
- require_relative 'payload'
2
- require_relative 'accumulator'
3
- require_relative 'observer'
1
+ require_relative 'entry'
2
+ require_relative 'entry_family'
4
3
 
5
- module Protor
4
+ class Protor
6
5
  class Registry
7
- HistogramDefaultBuckets = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10].freeze
6
+ attr_reader :families
8
7
 
9
- def initialize(options)
10
- @options = options
8
+ DEFAULT_BUCKET = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10].freeze
9
+
10
+ def initialize
11
+ @families = {}
11
12
  end
12
13
 
13
14
  def counter(metric_name, value, labels = {})
14
- verify_label(labels)
15
- counter_data.inc(metric_name, value, labels)
15
+ labels = stringify(labels)
16
+ fam = family(metric_name, :counter)
17
+
18
+ if (entry = fam[labels])
19
+ entry.value += value
20
+ else
21
+ fam[labels] = Entry.new(metric_name, :c, value, labels)
22
+ end
16
23
  end
17
24
 
18
25
  def gauge(metric_name, value, labels = {})
19
- verify_label(labels)
20
- gauge_data.set(metric_name, value, labels)
26
+ labels = stringify(labels)
27
+ fam = family(metric_name, :gauge)
28
+
29
+ if (entry = fam[labels])
30
+ entry.value = value
31
+ else
32
+ fam[labels] = Entry.new(metric_name, :g, value, labels)
33
+ end
21
34
  end
22
35
 
23
- def histogram(metric_name, value, labels = {}, buckets = HistogramDefaultBuckets)
24
- verify_label(labels)
25
- histogram_data.observe(metric_name, value, labels, buckets)
36
+ def histogram(metric_name, value, labels = {}, buckets = DEFAULT_BUCKET)
37
+ labels = stringify(labels)
38
+ fam = family(metric_name, :histogram)
39
+
40
+ entry = Entry.new(metric_name, :h, value, labels, buckets)
41
+ if (array = fam[labels])
42
+ array << entry
43
+ else
44
+ fam[labels] = [ entry ]
45
+ end
26
46
  end
27
47
 
28
48
  def each
29
- payload = Payload.new options.max_packet_size
30
- all_data.each do |data|
31
- unless payload.add(data)
32
- yield payload.to_s
33
-
34
- payload = Payload.new options.max_packet_size
35
- payload.add(data)
49
+ families.each_value do |family|
50
+ if family.type == :histogram
51
+ family.each{ |arr| arr.each{ |e| yield(e) }}
52
+ else
53
+ family.each{ |e| yield(e) }
36
54
  end
37
55
  end
38
-
39
- yield payload.to_s
40
56
  end
41
57
 
42
58
  def empty?
43
- [@counter, @gauge, @histogram].all?{ |metrics| metrics && metrics.empty? }
59
+ families.empty?
44
60
  end
45
61
 
46
62
  private
47
63
 
48
- attr_reader :options
49
-
50
- def verify_label(label)
51
- raise LabelError.new("Need Hash as labels, but found #{label.class.name}") if label && !label.is_a?(Hash)
52
- end
53
-
54
- def counter_data
55
- @counter ||= Accumulator.new(:counter)
64
+ def stringify(labels)
65
+ {}.tap do |h|
66
+ labels.each{ |k, v| h[k.to_s] = v.to_s }
67
+ end
56
68
  end
57
69
 
58
- def gauge_data
59
- @gauge ||= Accumulator.new(:gauge)
60
- end
70
+ def family(name, type)
71
+ families[name] ||= EntryFamily.new(name, type)
72
+ family = families[name]
73
+ raise IncompatibleTypeError.new(name, family.type, type) if family.type != type
61
74
 
62
- def histogram_data
63
- @histogram ||= Observer.new(:histogram)
75
+ return family
64
76
  end
77
+ end
65
78
 
66
- def all_data
67
- [counter_data.to_a, gauge_data.to_a, histogram_data.to_a].flatten
79
+ class IncompatibleTypeError < StandardError
80
+ def initialize(name, previous, now)
81
+ super("Incompatible type for metric #{name}, previously it was a #{previous}, now it is a #{now}")
68
82
  end
69
83
  end
70
84
  end
@@ -0,0 +1,31 @@
1
+ require 'socket'
2
+
3
+ class Protor
4
+ class UDPClient
5
+ attr_reader :host, :port, :formatter, :connection
6
+
7
+ def initialize(host, port, formatter)
8
+ @port = port
9
+ @host = host
10
+ @formatter = formatter
11
+ end
12
+
13
+ def publish(payload)
14
+ connect do |conn|
15
+ formatter.format(payload) do |msg|
16
+ conn.send(msg, 0)
17
+ end
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def connect
24
+ connection = UDPSocket.new
25
+ connection.connect(host, port)
26
+ yield(connection)
27
+ ensure
28
+ connection.close unless connection.closed?
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,50 @@
1
+ class Protor
2
+ class UDPFormatter
3
+ attr_reader :max_packet_size
4
+
5
+ LF = "\n".freeze
6
+
7
+ def initialize(max_packet_size)
8
+ @max_packet_size = max_packet_size
9
+ end
10
+
11
+ def format(registry)
12
+ return unless block_given?
13
+
14
+ str = ""
15
+ size = 0
16
+ registry.each do |entry|
17
+ line = stringify(entry)
18
+
19
+ if size + line.size > max_packet_size
20
+ yield(str)
21
+ str = line
22
+ size = line.size
23
+ else
24
+ str << line
25
+ size += line.size
26
+ end
27
+ end
28
+ yield(str)
29
+ end
30
+
31
+ private
32
+
33
+ def stringify(entry)
34
+ "#{ entry.name }|#{ entry.type }|".tap do |str|
35
+ str << "#{ additional_string(entry.additional) }|" unless entry.additional.empty?
36
+ str << "#{ labels_string(entry.labels) }|" unless entry.labels.empty?
37
+ str << "#{ entry.value }#{LF}"
38
+ end
39
+ end
40
+
41
+ def labels_string(labels)
42
+ labels.map{ |k, v| "#{k}=#{v}" }.join(';')
43
+ end
44
+
45
+ def additional_string(additional)
46
+ additional.join(';')
47
+ end
48
+ end
49
+ end
50
+
@@ -1,3 +1,3 @@
1
- module Protor
2
- VERSION = '0.0.11'
1
+ class Protor
2
+ VERSION = '0.1.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roland Rinfandi Utama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-22 00:00:00.000000000 Z
11
+ date: 2017-03-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -19,13 +19,12 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - README.md
21
21
  - lib/protor.rb
22
- - lib/protor/accumulator.rb
23
- - lib/protor/client.rb
24
- - lib/protor/configuration.rb
25
- - lib/protor/error.rb
26
- - lib/protor/observer.rb
27
- - lib/protor/payload.rb
22
+ - lib/protor/entry.rb
23
+ - lib/protor/entry_family.rb
24
+ - lib/protor/logger_client.rb
28
25
  - lib/protor/registry.rb
26
+ - lib/protor/udp_client.rb
27
+ - lib/protor/udp_formatter.rb
29
28
  - lib/protor/version.rb
30
29
  homepage: https://github.com/rolandhawk/protor-ruby
31
30
  licenses:
@@ -1,38 +0,0 @@
1
- module Protor
2
- class Accumulator
3
- def initialize(type)
4
- @data = {}
5
- @type = type
6
- end
7
-
8
- def inc(metric_name, value, labels = {})
9
- data[metric_name] ||= Hash.new(0)
10
- data[metric_name][labels] += value
11
- end
12
-
13
- def set(metric_name, value, labels = {})
14
- data[metric_name] ||= Hash.new(0)
15
- data[metric_name][labels] = value
16
- end
17
-
18
- def to_a
19
- array = []
20
-
21
- data.each do |metric_name, values|
22
- values.each do |labels, value|
23
- array << { metric_name: metric_name, labels: labels, value: value, type: type }
24
- end
25
- end
26
-
27
- return array
28
- end
29
-
30
- def empty?
31
- data.empty?
32
- end
33
-
34
- private
35
-
36
- attr_reader :type, :data
37
- end
38
- end
@@ -1,50 +0,0 @@
1
- require 'socket'
2
-
3
- module Protor
4
- class Client
5
- def initialize(configuration)
6
- @options = configuration
7
- @retries = 0
8
- end
9
-
10
- def publish(payload)
11
- connect
12
- payload.each do |message|
13
- send(message)
14
- end
15
- rescue Errno::EPERM, Errno::ECONNREFUSED => e
16
- options.logger.error(e)
17
- ensure
18
- close
19
- end
20
-
21
- private
22
-
23
- attr_reader :options, :connection, :retries
24
-
25
- def send(message)
26
- connection.send(message, 0)
27
- rescue Errno::EPERM => exception
28
- retries += 1
29
- if retries <= 3
30
- refresh && retry
31
- else
32
- raise exception
33
- end
34
- end
35
-
36
- def connect
37
- @connection = UDPSocket.new
38
- @connection.connect(options.host, options.port)
39
- end
40
-
41
- def refresh
42
- close
43
- connect
44
- end
45
-
46
- def close
47
- connection.close unless connection.closed?
48
- end
49
- end
50
- end
@@ -1,23 +0,0 @@
1
- require 'logger'
2
-
3
- module Protor
4
- class Configuration
5
- attr_writer :host, :port, :max_packet_size, :logger
6
-
7
- def host
8
- @host ||= 'localhost'
9
- end
10
-
11
- def port
12
- @port ||= 10601
13
- end
14
-
15
- def max_packet_size
16
- @max_packet_size ||= 56_607
17
- end
18
-
19
- def logger
20
- @logger ||= Logger.new(STDOUT)
21
- end
22
- end
23
- end
@@ -1,3 +0,0 @@
1
- module Protor
2
- class LabelError < StandardError; end
3
- end
@@ -1,47 +0,0 @@
1
- module Protor
2
- class Observer
3
- def initialize(type)
4
- @data = {}
5
- @type = type
6
- end
7
-
8
- def observe(metric_name, value, labels = {}, additional = [])
9
- data[metric_name] ||= { values: {} }
10
- data[metric_name][:values][labels] ||= []
11
-
12
- data[metric_name][:additional] = additional
13
- data[metric_name][:values][labels] << value
14
- end
15
-
16
- def to_a
17
- array = []
18
-
19
- data.each do |metric_name, values|
20
- first = true
21
- values[:values].each do |labels, value|
22
- value.each do |val|
23
- array << {
24
- metric_name: metric_name,
25
- labels: labels,
26
- value: val,
27
- additional: values[:additional],
28
- first: first,
29
- type: type
30
- }
31
- first = false
32
- end
33
- end
34
- end
35
-
36
- return array
37
- end
38
-
39
- def empty?
40
- data.empty?
41
- end
42
-
43
- private
44
-
45
- attr_reader :data, :type
46
- end
47
- end
@@ -1,106 +0,0 @@
1
- module Protor
2
- class Payload
3
-
4
- Lf = "\n".freeze
5
-
6
-
7
- def initialize(max_packet_size)
8
- @max_packet_size = max_packet_size
9
- @lines = []
10
- @total_size = 0
11
- end
12
-
13
- def add(data)
14
- data = data.dup
15
- data[:first] = true if lines.empty?
16
-
17
- if data[:labels]
18
- data[:labels].delete_if{ |k, v| v.to_s.empty? }
19
- else
20
- data[:labels] = {}
21
- end
22
-
23
- return false if packet_overflow?(data)
24
-
25
- self.common_labels = data[:labels]
26
- @total_size += data_size(data)
27
- @lines << data
28
- end
29
-
30
- def to_s
31
- str = first_line
32
- lines.each do |data|
33
- line = template(data)
34
- str << "#{line}#{Lf}"
35
- end
36
-
37
- return str
38
- end
39
-
40
- private
41
-
42
- attr_reader :common_labels, :lines, :total_size, :max_packet_size
43
-
44
- def data_size(data)
45
- size = 3
46
- [:metric_name, :value].each do |key|
47
- size += data[key].to_s.size
48
- end
49
-
50
- size += labels_string(data[:labels]).size + 1 if data[:labels]
51
-
52
- size += additional_string(data[:additional]).size + 1 if data[:first] && data[:additional]
53
-
54
- return size
55
- end
56
-
57
- def common_labels=(labels = {})
58
- @common_labels ||= labels.dup
59
- intersect(common_labels, labels)
60
- @common_labels.keep_if{ |k, v| labels.key?(k) }
61
- end
62
-
63
- def first_line
64
- if !common_labels || common_labels.empty?
65
- ""
66
- else
67
- "#{labels_string(common_labels)}#{Lf}"
68
- end
69
- end
70
-
71
- def template(data)
72
- labels = exclude_common(data[:labels])
73
-
74
- "#{ data[:metric_name] }|#{ data[:type][0] }|".tap do |str|
75
- str << "#{ additional_string(data[:additional]) }|" if data[:first] && data[:additional]
76
- str << "#{ labels_string(labels) }|" unless labels.empty?
77
- str << "#{ data[:value] }"
78
- end
79
- end
80
-
81
- def labels_string(labels)
82
- labels.map{ |k, v| "#{k}=#{v}" }.join(';')
83
- end
84
-
85
- def additional_string(additional)
86
- additional.join(';')
87
- end
88
-
89
- def intersect(a, b)
90
- a.keep_if{ |k, v| b[k] == v }
91
- end
92
-
93
- def exclude_common(labels)
94
- labels.keep_if{ |k, v| !common_labels[k] }
95
- end
96
-
97
- def packet_overflow?(data)
98
- backup = common_labels && common_labels.dup || data[:labels]
99
- intersect(backup, data[:labels])
100
- size = data_size(data)
101
-
102
- total_size + size - (labels_string(backup).size * lines.size) > max_packet_size
103
- end
104
- end
105
- end
106
-