iron_trail 0.0.6 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/iron_trail/db_functions.rb +21 -0
- data/lib/iron_trail/irontrail_log_row_function.sql +21 -7
- data/lib/iron_trail/version.rb +1 -1
- data/lib/iron_trail.rb +0 -11
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0eaa9c2070ae46d7386af196b943c47c495fba0485bc1b1956691e182ad099e
|
4
|
+
data.tar.gz: 732e39b8d5edba42b54a0f6bc67f6389d89fe1d037930c10dc4dff72a1afeb18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21577368bee6f5560d27488a4bfbc3cd064bdca3869a8538002838e10f64bcaf6c20f7ec2a0a1ce56d5690b9959adbe780e6b4d7b41e59af1a78f281f1ef413a
|
7
|
+
data.tar.gz: 7e6b3c94d40059c22aa929efb07f93fdcef8abc1ffc6ef63dfe10c7d862c31d39880cc1175ad953231675bb2dd644e23d7a0b2ba1e426544af330309c77e26bb
|
@@ -56,11 +56,32 @@ module IronTrail
|
|
56
56
|
connection.execute(query)
|
57
57
|
end
|
58
58
|
|
59
|
+
# Counting rows in Postgres is known to be a slow operation for large tables.
|
60
|
+
# Because of this, avoid using this for monitoring new errors. Instead,
|
61
|
+
# use the trigger_errors_metrics method.
|
59
62
|
def trigger_errors_count
|
60
63
|
stmt = 'SELECT COUNT(*) AS c FROM "irontrail_trigger_errors"'
|
61
64
|
connection.execute(stmt).first['c']
|
62
65
|
end
|
63
66
|
|
67
|
+
# This returns metrics intended to be used for monitoring. One can send
|
68
|
+
# these values to something like a Prometheus deployment and add monitoring
|
69
|
+
# on top of it.
|
70
|
+
# It should be much faster to run than trigger_errors_count.
|
71
|
+
#
|
72
|
+
# If the irontrail_trigger_errors table is empty, the resulting values
|
73
|
+
# will all be zero and never nil. This is so that data in a monitoring setup
|
74
|
+
# can tell apart a failure from a no-data scenario.
|
75
|
+
def trigger_errors_metrics
|
76
|
+
stmt = 'SELECT MAX(created_at) maxdate, MAX(id) AS maxid FROM "irontrail_trigger_errors"'
|
77
|
+
res = connection.execute(stmt).first
|
78
|
+
|
79
|
+
{
|
80
|
+
max_created_at: (res && res['maxdate'] && res['maxdate'].to_i) || 0,
|
81
|
+
max_id: (res && res['maxid']) || 0,
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
64
85
|
def collect_all_tables(schema: 'public')
|
65
86
|
# query pg_class rather than information schema because this way
|
66
87
|
# we can get only regular tables and ignore partitions.
|
@@ -11,10 +11,12 @@ DECLARE
|
|
11
11
|
new_obj JSONB;
|
12
12
|
actor_type TEXT;
|
13
13
|
actor_id TEXT;
|
14
|
+
created_at TIMESTAMP;
|
14
15
|
|
15
16
|
err_text TEXT; err_detail TEXT; err_hint TEXT; err_ctx TEXT;
|
16
17
|
BEGIN
|
17
18
|
SELECT split_part(split_part(current_query(), '/*IronTrail ', 2), ' IronTrail*/', 1) INTO it_meta;
|
19
|
+
|
18
20
|
IF (it_meta <> '') THEN
|
19
21
|
it_meta_obj = it_meta::JSONB;
|
20
22
|
|
@@ -28,17 +30,30 @@ BEGIN
|
|
28
30
|
END IF;
|
29
31
|
END IF;
|
30
32
|
|
33
|
+
old_obj = row_to_json(OLD);
|
34
|
+
new_obj = row_to_json(NEW);
|
35
|
+
|
36
|
+
IF (TG_OP = 'INSERT' AND new_obj ? 'created_at') THEN
|
37
|
+
created_at = NEW.created_at;
|
38
|
+
ELSIF (TG_OP = 'UPDATE' AND new_obj ? 'updated_at') THEN
|
39
|
+
created_at = NEW.updated_at;
|
40
|
+
END IF;
|
41
|
+
|
42
|
+
IF (created_at IS NULL) THEN
|
43
|
+
created_at = STATEMENT_TIMESTAMP();
|
44
|
+
ELSE
|
45
|
+
it_meta_obj = jsonb_set(COALESCE(it_meta_obj, '{}'::jsonb), array['_db_created_at'], TO_JSONB(STATEMENT_TIMESTAMP()));
|
46
|
+
END IF;
|
47
|
+
|
31
48
|
IF (TG_OP = 'INSERT') THEN
|
32
49
|
INSERT INTO "irontrail_changes" ("actor_id", "actor_type",
|
33
50
|
"rec_table", "operation", "rec_id", "rec_new", "metadata", "created_at")
|
34
51
|
VALUES (actor_id, actor_type,
|
35
|
-
TG_TABLE_NAME, 'i', NEW.id,
|
52
|
+
TG_TABLE_NAME, 'i', NEW.id, new_obj, it_meta_obj, created_at);
|
36
53
|
|
37
54
|
ELSIF (TG_OP = 'UPDATE') THEN
|
38
55
|
IF (OLD <> NEW) THEN
|
39
56
|
u_changes = jsonb_build_object();
|
40
|
-
old_obj = row_to_json(OLD);
|
41
|
-
new_obj = row_to_json(NEW);
|
42
57
|
|
43
58
|
FOR key IN (SELECT jsonb_object_keys(old_obj) UNION SELECT jsonb_object_keys(new_obj))
|
44
59
|
LOOP
|
@@ -51,14 +66,13 @@ BEGIN
|
|
51
66
|
|
52
67
|
INSERT INTO "irontrail_changes" ("actor_id", "actor_type", "rec_table", "operation",
|
53
68
|
"rec_id", "rec_old", "rec_new", "rec_delta", "metadata", "created_at")
|
54
|
-
VALUES (actor_id, actor_type, TG_TABLE_NAME, 'u', NEW.id,
|
55
|
-
u_changes, it_meta_obj, NOW());
|
69
|
+
VALUES (actor_id, actor_type, TG_TABLE_NAME, 'u', NEW.id, old_obj, new_obj, u_changes, it_meta_obj, created_at);
|
56
70
|
|
57
71
|
END IF;
|
58
72
|
ELSIF (TG_OP = 'DELETE') THEN
|
59
73
|
INSERT INTO "irontrail_changes" ("actor_id", "actor_type", "rec_table", "operation",
|
60
74
|
"rec_id", "rec_old", "metadata", "created_at")
|
61
|
-
VALUES (actor_id, actor_type, TG_TABLE_NAME, 'd', OLD.id,
|
75
|
+
VALUES (actor_id, actor_type, TG_TABLE_NAME, 'd', OLD.id, old_obj, it_meta_obj, created_at);
|
62
76
|
|
63
77
|
END IF;
|
64
78
|
RETURN NULL;
|
@@ -74,7 +88,7 @@ EXCEPTION
|
|
74
88
|
"err_text", "ex_detail", "ex_hint", "ex_ctx", "op", "table_name",
|
75
89
|
"old_data", "new_data", "query", "created_at")
|
76
90
|
VALUES (SQLSTATE, SQLERRM, err_text, err_detail, err_hint, err_ctx,
|
77
|
-
TG_OP, TG_TABLE_NAME, row_to_json(OLD), row_to_json(NEW), current_query(),
|
91
|
+
TG_OP, TG_TABLE_NAME, row_to_json(OLD), row_to_json(NEW), current_query(), STATEMENT_TIMESTAMP());
|
78
92
|
RETURN NULL;
|
79
93
|
END;
|
80
94
|
$$ LANGUAGE plpgsql;
|
data/lib/iron_trail/version.rb
CHANGED
data/lib/iron_trail.rb
CHANGED
@@ -52,17 +52,6 @@ module IronTrail
|
|
52
52
|
config.enable
|
53
53
|
end
|
54
54
|
|
55
|
-
# def test_mode!
|
56
|
-
# if [ENV['RAILS_ENV'], ENV['RACK_ENV']].include?('production')
|
57
|
-
# raise "IronTrail test mode cannot be enabled in production!"
|
58
|
-
# end
|
59
|
-
# @test_mode = true
|
60
|
-
# end
|
61
|
-
#
|
62
|
-
# def test_mode?
|
63
|
-
# @test_mode
|
64
|
-
# end
|
65
|
-
|
66
55
|
def ignore_table?(name)
|
67
56
|
(OWN_TABLES + (config.ignored_tables || [])).include?(name)
|
68
57
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iron_trail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- André Diego Piske
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-02-04 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: rails
|
@@ -153,7 +153,13 @@ files:
|
|
153
153
|
homepage: https://github.com/trusted/iron_trail
|
154
154
|
licenses:
|
155
155
|
- MIT
|
156
|
-
metadata:
|
156
|
+
metadata:
|
157
|
+
bug_tracker_uri: https://github.com/trusted/iron_trail/issues
|
158
|
+
changelog_uri: https://github.com/trusted/iron_trail/blob/main/CHANGELOG.md
|
159
|
+
documentation_uri: https://github.com/trusted/iron_trail/blob/main/README.md
|
160
|
+
homepage_uri: https://github.com/trusted/iron_trail
|
161
|
+
source_code_uri: https://github.com/trusted/iron_trail
|
162
|
+
wiki_uri: https://github.com/trusted/iron_trail/wiki
|
157
163
|
rdoc_options: []
|
158
164
|
require_paths:
|
159
165
|
- lib
|