Giter VIP home page Giter VIP logo

redmine_auditlog's Introduction

Redmine Auditlog

Provides full auditlog for user actions in Redmine instance.

How to use

  $ cd /path/to/redmine/plugins
  $ git clone https://github.com/RealEnder/redmine_auditlog
  $ cd redmine_auditlog
  $ rails generate audited:install # If using PostgreSQL, add "--audited-changes-column-type jsonb" for more efficient storage
  $ cd ../..
  $ rake db:migrate RAILS_ENV="production"

Then restart Redmine.

How to remove

  $ cd /path/to/redmine
  $ rake redmine:plugins:migrate NAME=redmine_auditlog VERSION=0 RAILS_ENV=production
  $ rm -rf plugins/redmine_auditlog

Then restart Redmine. This will not remove the audits table.

Compatible with: Redmine 3.4.x, 3.3.x, 3.2.x, 3.1.x, 3.0.x, 4.0.x, 4.1.x , 4.2.x
Tested with Redmine 3.4.6, 4.1.1, 4.2.10

License

Copyright 2018-2023 Alex Stanev [email protected]
This plugin is released under the GPL v3 license. See
LICENSE for more information.

redmine_auditlog's People

Contributors

realender avatar salmanmp avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

redmine_auditlog's Issues

Necessary index

Hi,
After a few months of usage, with >100000 issues, about 50 users, and a lot of activity, our server became very sluggish. I have investigated and saw that there was a query,

SELECT MAX(`version`) FROM `audits` WHERE `auditable_id` = 96 AND `auditable_type` = 'UserPreference';

which would take up to 20 seconds. As this looks frequently called, our mariadb was always working. To fix the issue, I've investigated and found that the existing index (auditable_index) was not used

MariaDB [redmine_production]> EXPLAIN SELECT MAX(`audits`.`version`) FROM `audits` WHERE `audits`.`auditable_id` = 96 AND `audits`.`auditable_type` = 'UserPreference';
+------+-------------+--------+------+-----------------+------+---------+------+---------+-------------+
| id   | select_type | table  | type | possible_keys   | key  | key_len | ref  | rows    | Extra       |
+------+-------------+--------+------+-----------------+------+---------+------+---------+-------------+
|    1 | SIMPLE      | audits | ALL  | auditable_index | NULL | NULL    | NULL | 1019400 | Using where |
+------+-------------+--------+------+-----------------+------+---------+------+---------+-------------+

Then, I've added manually the following index

CREATE INDEX auditable_index2 on audits (version, auditable_id, auditable_type);

and now (note that the new index is not used)

MariaDB [redmine_production]> EXPLAIN SELECT MAX(`version`) FROM `audits` WHERE `auditable_id` = 96 AND `auditable_type` = 'UserPreference';
+------+-------------+--------+------+-----------------+-----------------+---------+-------------+--------+-------------+
| id   | select_type | table  | type | possible_keys   | key             | key_len | ref         | rows   | Extra       |
+------+-------------+--------+------+-----------------+-----------------+---------+-------------+--------+-------------+
|    1 | SIMPLE      | audits | ref  | auditable_index | auditable_index | 581     | const,const | 509702 | Using where |
+------+-------------+--------+------+-----------------+-----------------+---------+-------------+--------+-------------+
1 row in set (0.001 sec)

As a result, the request is now taking less than a second.

Following install & login - unknown attribute 'action' for Audited::Audit.

Environment

Redmine version 4.1.1.stable
Ruby version 2.6.6-p146 (2020-03-31) [x64-mingw32]
Rails version 5.2.4.2
Environment production
Database adapter SQLServer

Log

Successful authentication for 'chris_lockwood' from 127.0.0.1 at 2021-01-16 19:33:05 UTC
Completed 500 Internal Server Error in 470ms (ActiveRecord: 209.6ms)

ActiveModel::UnknownAttributeError (unknown attribute 'action' for Audited::Audit.):

app/models/user.rb:435:in generate_session_token' app/controllers/application_controller.rb:88:in start_user_session'
app/controllers/application_controller.rb:168:in logged_user=' app/controllers/account_controller.rb:281:in successful_authentication'
app/controllers/account_controller.rb:227:in password_authentication' app/controllers/account_controller.rb:213:in authenticate_user'
app/controllers/account_controller.rb:40:in login' lib/redmine/sudo_mode.rb:65:in sudo_mode'

undefined method for nil:NilClass

$ rails generate audited:install --audited-changes-column-type jsonb RAILS_ENV=production
/home/redmine/web/rm.rubium.ru/public_html/plugins/redmine_sidekiq/lib/redmine_sidekiq/configure.rb:8:in `<class:Configure>': undefined method `[]' for nil:NilClass (NoMethodError)
	from /home/redmine/web/rm.rubium.ru/public_html/plugins/redmine_sidekiq/lib/redmine_sidekiq/configure.rb:4:in `<module:RedmineSidekiq>'
	from /home/redmine/web/rm.rubium.ru/public_html/plugins/redmine_sidekiq/lib/redmine_sidekiq/configure.rb:3:in `<top (required)>'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:274:in `block in require'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:240:in `load_dependency'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:274:in `require'
	from /home/redmine/web/rm.rubium.ru/public_html/plugins/redmine_sidekiq/init.rb:1:in `<top (required)>'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:274:in `block in require'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:240:in `load_dependency'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:274:in `require'
	from /home/redmine/web/rm.rubium.ru/public_html/lib/redmine/plugin.rb:155:in `block in load'
	from /home/redmine/web/rm.rubium.ru/public_html/lib/redmine/plugin.rb:146:in `each'
	from /home/redmine/web/rm.rubium.ru/public_html/lib/redmine/plugin.rb:146:in `load'
	from /home/redmine/web/rm.rubium.ru/public_html/config/initializers/30-redmine.rb:21:in `<top (required)>'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:268:in `load'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:268:in `block in load'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:240:in `load_dependency'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:268:in `load'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/engine.rb:652:in `block in load_config_initializer'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/notifications.rb:166:in `instrument'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/engine.rb:651:in `load_config_initializer'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/engine.rb:616:in `block (2 levels) in <class:Engine>'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/engine.rb:615:in `each'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/engine.rb:615:in `block in <class:Engine>'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/initializable.rb:30:in `instance_exec'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/initializable.rb:30:in `run'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/initializable.rb:55:in `block in run_initializers'
	from /home/redmine/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/tsort.rb:228:in `block in tsort_each'
	from /home/redmine/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
	from /home/redmine/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/tsort.rb:422:in `block (2 levels) in each_strongly_connected_component_from'
	from /home/redmine/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/tsort.rb:431:in `each_strongly_connected_component_from'
	from /home/redmine/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/tsort.rb:421:in `block in each_strongly_connected_component_from'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/initializable.rb:44:in `each'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/initializable.rb:44:in `tsort_each_child'
	from /home/redmine/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/tsort.rb:415:in `call'
	from /home/redmine/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/tsort.rb:415:in `each_strongly_connected_component_from'
	from /home/redmine/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/tsort.rb:349:in `block in each_strongly_connected_component'
	from /home/redmine/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/tsort.rb:347:in `each'
	from /home/redmine/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/tsort.rb:347:in `call'
	from /home/redmine/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/tsort.rb:347:in `each_strongly_connected_component'
	from /home/redmine/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/tsort.rb:226:in `tsort_each'
	from /home/redmine/.rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/tsort.rb:205:in `tsort_each'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/initializable.rb:54:in `run_initializers'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/application.rb:352:in `initialize!'
	from /home/redmine/web/rm.rubium.ru/public_html/config/environment.rb:14:in `<top (required)>'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:274:in `block in require'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:240:in `load_dependency'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:274:in `require'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/application.rb:328:in `require_environment!'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/commands/commands_tasks.rb:142:in `require_application_and_environment!'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/commands/commands_tasks.rb:128:in `generate_or_destroy'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/commands/commands_tasks.rb:50:in `generate'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
	from /home/redmine/.rvm/gems/ruby-2.3.3/gems/railties-4.2.7.1/lib/rails/commands.rb:17:in `<top (required)>'
	from bin/rails:4:in `require'
	from bin/rails:4:in `<main>'

Column audited_changes too small and a small instructions suggestion

In our redmine 4.1.1 instance we've noticed if the issue is too long, redmine will throw a 500 error because the audited_changes column is too small.
I fixed it with the SQL Command ALTER TABLE audits MODIFY COLUMN audited_changes LONGTEXT; it changes the type of the column from TEXT (65,535 bytes = 64 KiB) to LONGTEXT (4,294,967,295 bytes = 4 GiB) so there will be nearly no limit to issue lenght.

Also you really should change the command rails generate audited:install --audited-changes-column-type jsonb in the "How to use" description because it broke our MySQL database because there was no jsonb support, you could highlight it like:
For MySQL Databases:
rails generate audited:install

For PostgreSQL Databases:
rails generate audited:install --audited-changes-column-type jsonb

grafik

Redmine 5.0 (ruby 3.0) support

Seems like plugin needs update to work in redmine 5.0:

bundle exec rake db:migrate RAILS_ENV=production 
rake aborted!
LoadError: cannot load such file -- redmine_auditlog
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/zeitwerk-2.5.4/lib/zeitwerk/kernel.rb:35:in `require'
/usr/share/webapps/redmine/plugins/redmine_auditlog/init.rb:1:in `<top (required)>'
/usr/share/webapps/redmine/lib/redmine/plugin_loader.rb:31:in `load'
/usr/share/webapps/redmine/lib/redmine/plugin_loader.rb:31:in `run_initializer'
/usr/share/webapps/redmine/lib/redmine/plugin_loader.rb:108:in `each'
/usr/share/webapps/redmine/lib/redmine/plugin_loader.rb:108:in `block in load'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/callbacks.rb:427:in `instance_exec'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/callbacks.rb:427:in `block in make_lambda'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/callbacks.rb:198:in `block (2 levels) in halting'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/callbacks.rb:604:in `block (2 levels) in default_terminator'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/callbacks.rb:603:in `catch'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/callbacks.rb:603:in `block in default_terminator'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/callbacks.rb:199:in `block in halting'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/callbacks.rb:512:in `block in invoke_before'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/callbacks.rb:512:in `each'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/callbacks.rb:512:in `invoke_before'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/callbacks.rb:105:in `run_callbacks'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/reloader.rb:88:in `prepare!'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/railties-6.1.4.7/lib/rails/application/finisher.rb:124:in `block in <module:Finisher>'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/railties-6.1.4.7/lib/rails/initializable.rb:32:in `instance_exec'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/railties-6.1.4.7/lib/rails/initializable.rb:32:in `run'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/railties-6.1.4.7/lib/rails/initializable.rb:61:in `block in run_initializers'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/railties-6.1.4.7/lib/rails/initializable.rb:60:in `run_initializers'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/railties-6.1.4.7/lib/rails/application.rb:391:in `initialize!'
/usr/share/webapps/redmine/config/environment.rb:16:in `<top (required)>'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/zeitwerk-2.5.4/lib/zeitwerk/kernel.rb:35:in `require'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/dependencies.rb:332:in `block in require'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/dependencies.rb:299:in `load_dependency'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.7/lib/active_support/dependencies.rb:332:in `require'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/railties-6.1.4.7/lib/rails/application.rb:367:in `require_environment!'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/railties-6.1.4.7/lib/rails/application.rb:533:in `block in run_tasks_blocks'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/bundler-2.2.31/lib/bundler/cli/exec.rb:58:in `load'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/bundler-2.2.31/lib/bundler/cli/exec.rb:58:in `kernel_load'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/bundler-2.2.31/lib/bundler/cli/exec.rb:23:in `run'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/bundler-2.2.31/lib/bundler/cli.rb:478:in `exec'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/bundler-2.2.31/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/bundler-2.2.31/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/bundler-2.2.31/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/bundler-2.2.31/lib/bundler/cli.rb:31:in `dispatch'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/bundler-2.2.31/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/bundler-2.2.31/lib/bundler/cli.rb:25:in `start'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/bundler-2.2.31/exe/bundle:49:in `block in <top (required)>'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/bundler-2.2.31/lib/bundler/friendly_errors.rb:103:in `with_friendly_errors'
/usr/share/webapps/redmine/vendor/bundle/ruby/3.0.0/gems/bundler-2.2.31/exe/bundle:37:in `<top (required)>'
/usr/sbin/bundle:25:in `load'
/usr/sbin/bundle:25:in `<main>'
Tasks: TOP => db:migrate => db:load_config => environment
(See full trace by running task with --trace)

Viewing audit log

Hi,

Is it possible to view/export audit log with redmine instance?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.