Class: Proxy::Abrt::HostReport

Inherits:
Object
  • Object
show all
Includes:
Log
Defined in:
lib/smart_proxy_abrt/abrt_lib.rb

Defined Under Namespace

Classes: AggregatedReport, Error

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fname) ⇒ HostReport

Returns a new instance of HostReport.



104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 104

def initialize(fname)
  contents = IO.read(fname)
  json = JSON.parse(contents)

  report = json["report"]
  hash = HostReport.duphash report
  ar = AggregatedReport.new(json["report"], 1, hash, json["reported_at"])
  @reports = [ar]
  # index the array elements by duphash, if they have one
  @by_hash = {}
  @by_hash[hash] = ar unless hash.nil?
  @files = [fname]
  @host = json["host"]
end

Instance Attribute Details

#by_hashObject (readonly)

Returns the value of attribute by_hash.



102
103
104
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 102

def by_hash
  @by_hash
end

#filesObject (readonly)

Returns the value of attribute files.



102
103
104
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 102

def files
  @files
end

#hostObject (readonly)

Returns the value of attribute host.



102
103
104
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 102

def host
  @host
end

#reportsObject (readonly)

Returns the value of attribute reports.



102
103
104
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 102

def reports
  @reports
end

Class Method Details

.duphash(report) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 208

def self.duphash(report)
  return nil if !Proxy::Abrt::Plugin.settings.aggregate_reports

  begin
    satyr_report = Satyr::Report.new report.to_json
    stacktrace = satyr_report.stacktrace
    thread = stacktrace.find_crash_thread
    thread.duphash
  rescue StandardError => e
    logger.error "Error computing duphash: #{e}"
    nil
  end
end

.load_from_spoolObject



171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 171

def self.load_from_spool
  reports = []
  report_files = Dir[File.join(HostReport.spooldir, "ureport-*")]
  report_files.each do |fname|
    begin
      reports << new(fname)
    rescue StandardError => e
      logger.error "Failed to parse report #{fname}: #{e}"
    end
  end
  reports
end

.save(host, report, reported_at = nil) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 150

def self.save(host, report, reported_at=nil)
  # create the spool dir if it does not exist
  FileUtils.mkdir_p HostReport.spooldir

  reported_at ||= Time.now.utc
  on_disk_report = { "host" => host, "report" => report , "reported_at" => reported_at.to_s }

  # write report to temporary file
  temp_fname = with_unique_filename "new-" do |temp_fname|
    File.open temp_fname, File::WRONLY|File::CREAT|File::EXCL do |tmpfile|
      tmpfile.write(on_disk_report.to_json)
    end
  end

  # rename it
  with_unique_filename ("ureport-" + DateTime.now.iso8601 + "-") do |final_fname|
    File.link temp_fname, final_fname
    File.unlink temp_fname
  end
end

.spooldirObject



240
241
242
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 240

def self.spooldir
  Proxy::Abrt::Plugin.settings.spooldir || File.join(APP_ROOT, "spool/foreman-proxy-abrt")
end

.unique_filename(prefix) ⇒ Object



222
223
224
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 222

def self.unique_filename(prefix)
  File.join(HostReport.spooldir, prefix + Proxy::Abrt::random_alpha_string(8))
end

.with_unique_filename(prefix) ⇒ Object



226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 226

def self.with_unique_filename(prefix)
  filename = unique_filename prefix
  tries_left = 5
  begin
    yield filename
  rescue Errno::EEXIST => e
    filename = unique_filename prefix
    tries_left -= 1
    retry if tries_left > 0
    raise HostReport::Error, "Unable to create unique file"
  end
  filename
end

Instance Method Details

#merge(other) ⇒ Object

Raises:



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 119

def merge(other)
  raise HostReport::Error, "Host names do not match" unless @host == other.host

  other.reports.each do |ar|
    if !ar.hash.nil? && @by_hash.has_key?(ar.hash)
      # we already have this report, just increment the counter
      found_report = @by_hash[ar.hash]
      found_report.count += ar.count
      found_report.reported_at = [found_report.reported_at, ar.reported_at].min
    else
      # we either don't have this report or it has no hash
      @reports << ar
      @by_hash[ar.hash] = ar unless ar.hash.nil?
    end
  end
  @files += other.files
end

#send_to_foremanObject



137
138
139
140
141
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 137

def send_to_foreman
  foreman_report = create_foreman_report
  logger.debug "Sending #{foreman_report}"
  Proxy::HttpRequest::ForemanRequest.new.send_request("/api/abrt_reports", foreman_report.to_json)
end


143
144
145
146
147
148
# File 'lib/smart_proxy_abrt/abrt_lib.rb', line 143

def unlink
  @files.each do |fname|
    logger.debug "Deleting #{fname}"
    File.unlink(fname)
  end
end