mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 01:01:39 -05:00
Add basic telemetry
This commit is contained in:
parent
2b77a58dbf
commit
f10f78999d
8 changed files with 160 additions and 1 deletions
11
app/jobs/telemetry_sending_job.rb
Normal file
11
app/jobs/telemetry_sending_job.rb
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TelemetrySendingJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
def perform
|
||||
data = Telemetry::Gather.new.call
|
||||
|
||||
Telemetry::Send.new(data).call
|
||||
end
|
||||
end
|
||||
32
app/services/telemetry/gather.rb
Normal file
32
app/services/telemetry/gather.rb
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Telemetry::Gather
|
||||
def initialize(measurement: 'dawarich_usage_metrics')
|
||||
@measurement = measurement
|
||||
end
|
||||
|
||||
def call
|
||||
{
|
||||
measurement:,
|
||||
timestamp: Time.current.to_i,
|
||||
tags: { instance_id: },
|
||||
fields: { dau:, app_version: }
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :measurement
|
||||
|
||||
def instance_id
|
||||
@instance_id ||= Digest::SHA2.hexdigest(User.first.api_key)
|
||||
end
|
||||
|
||||
def app_version
|
||||
"\"#{APP_VERSION}\""
|
||||
end
|
||||
|
||||
def dau
|
||||
User.where(last_sign_in_at: Time.zone.today.beginning_of_day..Time.zone.today.end_of_day).count
|
||||
end
|
||||
end
|
||||
44
app/services/telemetry/send.rb
Normal file
44
app/services/telemetry/send.rb
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Telemetry::Send
|
||||
BUCKET = 'dawarich_metrics'
|
||||
ORG = 'monitoring'
|
||||
|
||||
def initialize(payload)
|
||||
@payload = payload
|
||||
end
|
||||
|
||||
def call
|
||||
line_protocol = build_line_protocol
|
||||
response = send_request(line_protocol)
|
||||
handle_response(response)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :payload
|
||||
|
||||
def build_line_protocol
|
||||
tag_string = payload[:tags].map { |k, v| "#{k}=#{v}" }.join(',')
|
||||
field_string = payload[:fields].map { |k, v| "#{k}=#{v}" }.join(',')
|
||||
|
||||
"#{payload[:measurement]},#{tag_string} #{field_string} #{payload[:timestamp].to_i}"
|
||||
end
|
||||
|
||||
def send_request(line_protocol)
|
||||
HTTParty.post(
|
||||
"#{TELEMETRY_URL}?org=#{ORG}&bucket=#{BUCKET}&precision=s",
|
||||
body: line_protocol,
|
||||
headers: {
|
||||
'Authorization' => "Token #{Base64.decode64(TELEMETRY_STRING)}",
|
||||
'Content-Type' => 'text/plain'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
def handle_response(response)
|
||||
Rails.logger.error("InfluxDB write failed: #{response.body}") unless response.success?
|
||||
|
||||
response
|
||||
end
|
||||
end
|
||||
|
|
@ -6,3 +6,5 @@ PHOTON_API_HOST = ENV.fetch('PHOTON_API_HOST', nil)
|
|||
PHOTON_API_USE_HTTPS = ENV.fetch('PHOTON_API_USE_HTTPS', 'true') == 'true'
|
||||
DISTANCE_UNIT = ENV.fetch('DISTANCE_UNIT', 'km').to_sym
|
||||
APP_VERSION = File.read('.app_version').strip
|
||||
TELEMETRY_STRING = Base64.encode64('IjVFvb8j3P9-ArqhSGav9j8YcJaQiuNIzkfOPKQDk2lvKXqb8t1NSRv50oBkaKtlrB_ZRzO9NdurpMtncV_HYQ==')
|
||||
TELEMETRY_URL = 'https://influxdb2.frey.today/api/v2/write'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddDeviseTrackableColumnsToUsers < ActiveRecord::Migration[7.2]
|
||||
def change
|
||||
change_table :users, bulk: true do |t|
|
||||
t.integer :sign_in_count, default: 0, null: false
|
||||
t.datetime :current_sign_in_at
|
||||
t.datetime :last_sign_in_at
|
||||
t.string :current_sign_in_ip
|
||||
t.string :last_sign_in_ip
|
||||
end
|
||||
end
|
||||
end
|
||||
9
db/schema.rb
generated
9
db/schema.rb
generated
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.2].define(version: 2024_11_28_095325) do
|
||||
ActiveRecord::Schema[7.2].define(version: 2024_12_05_160055) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
|
|
@ -155,6 +155,7 @@ ActiveRecord::Schema[7.2].define(version: 2024_11_28_095325) do
|
|||
t.bigint "user_id"
|
||||
t.jsonb "geodata", default: {}, null: false
|
||||
t.bigint "visit_id"
|
||||
t.datetime "reverse_geocoded_at"
|
||||
t.index ["altitude"], name: "index_points_on_altitude"
|
||||
t.index ["battery"], name: "index_points_on_battery"
|
||||
t.index ["battery_status"], name: "index_points_on_battery_status"
|
||||
|
|
@ -164,6 +165,7 @@ ActiveRecord::Schema[7.2].define(version: 2024_11_28_095325) do
|
|||
t.index ["geodata"], name: "index_points_on_geodata", using: :gin
|
||||
t.index ["import_id"], name: "index_points_on_import_id"
|
||||
t.index ["latitude", "longitude"], name: "index_points_on_latitude_and_longitude"
|
||||
t.index ["reverse_geocoded_at"], name: "index_points_on_reverse_geocoded_at"
|
||||
t.index ["timestamp"], name: "index_points_on_timestamp"
|
||||
t.index ["trigger"], name: "index_points_on_trigger"
|
||||
t.index ["user_id"], name: "index_points_on_user_id"
|
||||
|
|
@ -208,6 +210,11 @@ ActiveRecord::Schema[7.2].define(version: 2024_11_28_095325) do
|
|||
t.string "theme", default: "dark", null: false
|
||||
t.jsonb "settings", default: {"fog_of_war_meters"=>"100", "meters_between_routes"=>"1000", "minutes_between_routes"=>"60"}
|
||||
t.boolean "admin", default: false
|
||||
t.integer "sign_in_count", default: 0, null: false
|
||||
t.datetime "current_sign_in_at"
|
||||
t.datetime "last_sign_in_at"
|
||||
t.string "current_sign_in_ip"
|
||||
t.string "last_sign_in_ip"
|
||||
t.index ["email"], name: "index_users_on_email", unique: true
|
||||
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
||||
end
|
||||
|
|
|
|||
5
spec/jobs/telemetry_sending_job_spec.rb
Normal file
5
spec/jobs/telemetry_sending_job_spec.rb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe TelemetrySendingJob, type: :job do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
45
spec/services/telemetry/gather_spec.rb
Normal file
45
spec/services/telemetry/gather_spec.rb
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Telemetry::Gather do
|
||||
let!(:user) { create(:user, last_sign_in_at: Time.zone.today) }
|
||||
|
||||
describe '#call' do
|
||||
subject(:gather) { described_class.new.call }
|
||||
|
||||
it 'returns a hash with measurement, timestamp, tags, and fields' do
|
||||
expect(gather).to include(:measurement, :timestamp, :tags, :fields)
|
||||
end
|
||||
|
||||
it 'includes the correct measurement' do
|
||||
expect(gather[:measurement]).to eq('dawarich_usage_metrics')
|
||||
end
|
||||
|
||||
it 'includes the current timestamp' do
|
||||
expect(gather[:timestamp]).to be_within(1).of(Time.current.to_i)
|
||||
end
|
||||
|
||||
it 'includes the correct instance_id in tags' do
|
||||
expect(gather[:tags][:instance_id]).to eq(Digest::SHA2.hexdigest(user.api_key))
|
||||
end
|
||||
|
||||
it 'includes the correct app_version in fields' do
|
||||
expect(gather[:fields][:app_version]).to eq("\"#{APP_VERSION}\"")
|
||||
end
|
||||
|
||||
it 'includes the correct dau in fields' do
|
||||
expect(gather[:fields][:dau]).to eq(1)
|
||||
end
|
||||
|
||||
context 'with a custom measurement' do
|
||||
let(:measurement) { 'custom_measurement' }
|
||||
|
||||
subject(:gather) { described_class.new(measurement:).call }
|
||||
|
||||
it 'includes the correct measurement' do
|
||||
expect(gather[:measurement]).to eq('custom_measurement')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue