aliyun-log 0.2.12 → 0.2.13

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba1bcbd83277ca8da27978ecd7a603a205a19c1600b11f359135e2629e6f61c4
4
- data.tar.gz: d1e731f6b181167ef11004c7c79bbbef9acd290be531a08a24bb6f87134cfaac
3
+ metadata.gz: 5d6574ee8e72a65c178f4cdc28c61e63379999e51166c95756b9ffd6b367f47a
4
+ data.tar.gz: 8fdce159cd971c94c966b20db9926653a16e4bd5efaee918f619a6f0bf00a9e8
5
5
  SHA512:
6
- metadata.gz: 850989116e4820287e15fbe5361319f1043d4a1c3e7991bab947187bcac2d0114ee9244df26c4c132cd29d400752b4f18a6c0a3bcccaaabdda151858829b19e4
7
- data.tar.gz: c03afaddd81499c4cb36be357d9894eccf2574fa009afa2d57f7d01e61885534a60b94f4bc2dfaa315e5db0862481225966fc71f27fb8ce1d6a1686284f90e40
6
+ metadata.gz: 13ce9aed0a16e0c0a47fe8baadc45215967fd33cef33bece8bdfca0148a565155f347860d3bf986091b965419e04d513e19756c87b6f52ac32879188f07f3a11
7
+ data.tar.gz: f7c441bdb8ae2f3a768b236fb1bc8b86ad0c4965324b9323142565d50ed776b632ff11ba2036af7b1d1058968daeabe14080f792cbf2d438c777a6f4a25f17cf
@@ -16,11 +16,17 @@ module Aliyun
16
16
  repeated Content, :contents, 2
17
17
  end
18
18
 
19
+ class LogTag < ::Protobuf::Message
20
+ required :string, :key, 1
21
+ required :string, :value, 2
22
+ end
23
+
19
24
  class LogGroup < ::Protobuf::Message
20
25
  repeated Log, :logs, 1
21
26
  optional :string, :reserved, 2
22
27
  optional :string, :topic, 3
23
28
  optional :string, :source, 4
29
+ repeated LogTag, :log_tags, 6
24
30
  end
25
31
  end
26
32
  end
@@ -4,7 +4,7 @@ require 'active_support'
4
4
  require 'active_support/time'
5
5
  require 'active_support/core_ext'
6
6
  require 'active_model'
7
- require 'forwardable'
7
+ require 'monitor'
8
8
 
9
9
  require_relative 'record/exception'
10
10
  require_relative 'record/field'
@@ -22,16 +22,21 @@ module Aliyun
22
22
 
23
23
  class_attribute :options, instance_accessor: false, default: {}
24
24
  class_attribute :base_class, instance_accessor: false, default: self
25
- class_attribute :log_connection, instance_accessor: false
26
25
  class_attribute :_schema_load, default: false
27
26
 
28
27
  Log.included_models << self unless Log.included_models.include? self
29
28
 
29
+ field :__time__, type: :long, cast_type: :integer
30
+ field :__topic__
31
+ field :__source__
32
+
30
33
  field :created_at, type: :text, cast_type: :datetime if Config.timestamps
31
34
 
32
35
  define_model_callbacks :save, :create, :initialize
33
36
 
34
37
  before_save :set_created_at
38
+
39
+ @lock = Monitor.new
35
40
  end
36
41
 
37
42
  include Field
@@ -79,6 +84,10 @@ module Aliyun
79
84
  end
80
85
  end
81
86
 
87
+ def new_record?
88
+ @new_record == true
89
+ end
90
+
82
91
  def inspect
83
92
  inspection = if defined?(@attributes) && @attributes
84
93
  self.class.attributes.keys.collect do |name|
@@ -20,6 +20,7 @@ module Aliyun
20
20
 
21
21
  included do
22
22
  class_attribute :attributes, instance_accessor: false, default: {}
23
+ class_attribute :tag_attributes, instance_accessor: false, default: {}
23
24
  extend Common::Logging
24
25
  end
25
26
 
@@ -31,7 +32,11 @@ module Aliyun
31
32
  end
32
33
 
33
34
  named = name.to_s
34
- self.attributes = attributes.merge(name => { type: type }.merge(options))
35
+ if options[:log_tag]
36
+ self.tag_attributes = tag_attributes.merge(name => { type: type }.merge(options))
37
+ else
38
+ self.attributes = attributes.merge(name => { type: type }.merge(options))
39
+ end
35
40
 
36
41
  warn_about_method_overriding(name, name)
37
42
  warn_about_method_overriding("#{named}=", name)
@@ -4,6 +4,14 @@ module Aliyun
4
4
  module Log
5
5
  module Record
6
6
  module Persistence
7
+ RESERVED_FIELDS = %i[
8
+ __time__
9
+ __topic__
10
+ __source__
11
+ __partition_time__
12
+ __extract_others__
13
+ ].freeze
14
+
7
15
  extend ActiveSupport::Concern
8
16
 
9
17
  module ClassMethods
@@ -40,11 +48,12 @@ module Aliyun
40
48
  end
41
49
 
42
50
  def auto_load_schema
43
- return if _schema_load
44
-
45
- create_logstore
46
- sync_index
47
- self._schema_load = true
51
+ @lock.synchronize do
52
+ return if _schema_load
53
+ create_logstore
54
+ sync_index
55
+ self._schema_load = true
56
+ end
48
57
  end
49
58
 
50
59
  def has_index?
@@ -54,19 +63,23 @@ module Aliyun
54
63
  false
55
64
  end
56
65
 
57
- def create(data, opts = {})
66
+ def create(data, force = false)
58
67
  auto_load_schema
59
68
  if data.is_a?(Array)
60
- logs = data.map do |log_attr|
61
- new(log_attr).save_array
69
+ # TODO batch insert
70
+ data.each do |log|
71
+ saved = new(log).save(force)
72
+ return false unless saved
62
73
  end
63
- res = Log.record_connection.put_log(project_name, logstore_name, logs, opts)
64
- res.code == 200
65
74
  else
66
- new(data).save
75
+ new(data).save(force)
67
76
  end
68
77
  end
69
78
 
79
+ def create!(data)
80
+ create(data, true)
81
+ end
82
+
70
83
  private
71
84
 
72
85
  def evaluate_default_value(val)
@@ -80,11 +93,12 @@ module Aliyun
80
93
  end
81
94
 
82
95
  def field_indices
83
- if options[:field_index] == false
84
- attributes.select { |_, value| value[:index] == true }
85
- else
86
- attributes.reject { |_, value| value[:index] == false }
87
- end
96
+ indices = if options[:field_index] == false
97
+ attributes.select { |_, value| value[:index] == true }
98
+ else
99
+ attributes.reject { |_, value| value[:index] == false }
100
+ end
101
+ indices.reject { |key, _| RESERVED_FIELDS.include?(key) }
88
102
  end
89
103
 
90
104
  def create_index
@@ -125,38 +139,68 @@ module Aliyun
125
139
  end
126
140
  end
127
141
 
142
+ def dump_log_tags
143
+ log_tags = {}
144
+ self.class.tag_attributes.map do |key, options|
145
+ log_tags[key] = TypeCasting.dump_field(attributes[key], options)
146
+ end
147
+ log_tags.compact
148
+ end
149
+
128
150
  def dump_attributes
129
151
  attributes.dup.tap do |tap|
130
152
  tap.each do |k, v|
131
- tap[k] = TypeCasting.dump_field(v, self.class.attributes[k])
153
+ if self.class.attributes[k][:log_tag] || RESERVED_FIELDS.include?(k)
154
+ tap.delete(k)
155
+ else
156
+ tap[k] = TypeCasting.dump_field(v, self.class.attributes[k])
157
+ end
132
158
  end
133
159
  end
134
160
  end
135
161
 
136
- def save
162
+ def save(force = false)
137
163
  self.class.auto_load_schema
138
164
  run_callbacks(:create) do
139
165
  run_callbacks(:save) do
140
- if valid?
141
- res = Log.record_connection.put_log(
142
- self.class.project_name,
143
- self.class.logstore_name,
144
- dump_attributes
145
- )
146
- res.code == 200
147
- else
148
- false
149
- end
166
+ force && validate!
167
+ return false unless valid?
168
+ saved = put_logs
169
+ @new_record = false if saved
170
+ saved
150
171
  end
151
172
  end
152
173
  end
153
174
 
154
- def save_array
155
- run_callbacks(:create) do
156
- run_callbacks(:save) do
157
- validate! && dump_attributes
158
- end
159
- end
175
+ def save!
176
+ save(true)
177
+ end
178
+
179
+ private
180
+
181
+ def put_logs
182
+ log_tags = []
183
+ dump_log_tags.each do |k, v|
184
+ log_tags << Protobuf::LogTag.new(key: k, value: v)
185
+ end
186
+ lg = Protobuf::LogGroup.new(
187
+ logs: [generate_log],
188
+ log_tags: log_tags,
189
+ topic: read_attribute(:__topic__),
190
+ source: read_attribute(:__source__)
191
+ )
192
+ res = Log.record_connection.put_logs(
193
+ self.class.project_name,
194
+ self.class.logstore_name,
195
+ lg
196
+ )
197
+ res.code == 200
198
+ end
199
+
200
+ def generate_log
201
+ time = read_attribute(:__time__) || Time.now.to_i
202
+ contents = dump_attributes.map { |k, v| { key: k, value: v.to_s } }
203
+ Protobuf::Log.new(time: time, contents: contents)
160
204
  end
161
205
  end
162
206
  end
@@ -216,7 +216,7 @@ module Aliyun
216
216
  sql_query << "ORDER BY #{opts[:order]}" if opts[:order].present?
217
217
  if sql_query.present? || opts[:select].present?
218
218
  sql_query.insert(0, "SELECT #{opts[:select] || '*'}")
219
- sql_query.insert(1, 'FROM log')
219
+ sql_query.insert(1, 'FROM log') unless opts[:select]&.match?(/from\s+log/i)
220
220
  if opts[:line] || opts[:page] || opts[:offset]
221
221
  parse_page
222
222
  sql_query << "LIMIT #{@opts[:offset]},#{@opts[:line]}"
@@ -250,7 +250,7 @@ module Aliyun
250
250
  def sanitize_hash(search_content)
251
251
  return search_content unless search_content.is_a?(Hash)
252
252
 
253
- search_content.select { |_, v| v.present? }.map do |key, value|
253
+ search_content.reject { |_, v| v.nil? }.map do |key, value|
254
254
  options = @klass.attributes[:"#{key}"]
255
255
  unless options
256
256
  raise UnknownAttributeError, "unknown field '#{key}' for #{@klass.name}."
@@ -259,14 +259,18 @@ module Aliyun
259
259
  raise_if_hash_quote(value)
260
260
 
261
261
  cast_type = options[:cast_type]
262
+
263
+ is_tag = @klass.tag_attributes[:"#{key}"]
264
+ key = :"__tag__:#{key}" if is_tag
262
265
  if value.is_a?(Array)
263
- values = value.uniq.map { |v| _quote(cast_type, v) }
266
+ values = value.uniq.map { |v| is_tag ? v : _quote(cast_type, v) }
264
267
  str_values = values.map { |v| "#{key}: #{v}" }.join(' OR ')
265
268
  values.size > 1 ? "(#{str_values})" : str_values
266
269
  elsif value.is_a?(Range)
267
270
  "#{key} in [#{value.begin} #{value.end}]"
268
271
  else
269
- "#{key}: #{_quote(cast_type, value)}"
272
+ quote_value = is_tag ? value : _quote(cast_type, value)
273
+ "#{key}: #{quote_value}"
270
274
  end
271
275
  end.join(' AND ')
272
276
  end
@@ -55,7 +55,17 @@ module Aliyun
55
55
  end
56
56
  end
57
57
 
58
- class StringType < Value; end
58
+ class StringType < Value
59
+ def cast(value)
60
+ if value.nil?
61
+ ''
62
+ elsif value.is_a? String
63
+ value.dup
64
+ else
65
+ value.to_s
66
+ end
67
+ end
68
+ end
59
69
 
60
70
  class DateType < Value
61
71
  def cast(value)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Aliyun
4
4
  module Log
5
- VERSION = '0.2.12'
5
+ VERSION = '0.2.13'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aliyun-log
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.12
4
+ version: 0.2.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yingce Liu
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-13 00:00:00.000000000 Z
11
+ date: 2020-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel