Instrumentation
The instrumentation plugin publishes events for various
operations to a centralized notification component. In addition to that, it
provides default logging for these events.
Shrine.plugin :instrumentationBy default, the notification component is assumed to be ActiveSupport::Notifications, but dry-monitor is supported as well:
# Gemfile
gem "dry-monitor"require "dry-monitor"
Shrine.plugin :instrumentation, notifications: Dry::Monitor::Notifications.new(:test)Logging
By default, the instrumentation plugin adds logging to the instrumented
events:
uploaded_file = Shrine.upload(StringIO.new("file"), :store)
uploaded_file.exists?
uploaded_file.download
uploaded_file.deleteMetadata (32ms) – {:storage=>:store, :io=>StringIO, :uploader=>Shrine}
Upload (1523ms) – {:storage=>:store, :location=>"ed0e30ddec8b97813f2c1f4cfd1700b4", :io=>StringIO, :upload_options=>{}, :uploader=>Shrine}
Exists (755ms) – {:storage=>:store, :location=>"ed0e30ddec8b97813f2c1f4cfd1700b4", :uploader=>Shrine}
Download (1002ms) – {:storage=>:store, :location=>"ed0e30ddec8b97813f2c1f4cfd1700b4", :download_options=>{}, :uploader=>Shrine}
Delete (700ms) – {:storage=>:store, :location=>"ed0e30ddec8b97813f2c1f4cfd1700b4", :uploader=>Shrine}
It uses Shrine.logger for logging, which allows you to change where and how
are the logs going to be written:
Shrine.logger = Rails.logger # in Rails appsYou can choose to log only certain events, e.g. we can exclude metadata extraction:
Shrine.plugin :instrumentation, log_events: [
:upload,
:exists,
:download,
:delete,
]You can also use your own log subscriber:
Shrine.plugin :instrumentation, log_subscriber: -> (event) {
Shrine.logger.info JSON.generate(name: event.name, duration: event.duration, **event.payload)
}{"name":"metadata","duration":0,"storage":"store","io":"#<StringIO:0x00007fd1d4a1b9d8>","options":{},"uploader":"Shrine"}
{"name":"upload","duration":0,"storage":"store","location":"dbeb3c3ed664059eb41a608e54a29f54","io":"#<StringIO:0x00007fd1d4a1b9d8>","upload_options":{},"options":{"location":"dbeb3c3ed664059eb41a608e54a29f54","metadata":{"filename":null,"size":4,"mime_type":null}},"uploader":"Shrine"}
{"name":"exists","duration":0,"storage":"store","location":"dbeb3c3ed664059eb41a608e54a29f54","uploader":"Shrine"}
{"name":"download","duration":0,"storage":"store","location":"dbeb3c3ed664059eb41a608e54a29f54","download_options":{},"uploader":"Shrine"}
{"name":"delete","duration":0,"storage":"store","location":"dbeb3c3ed664059eb41a608e54a29f54","uploader":"Shrine"}
Or disable logging altogether:
Shrine.plugin :instrumentation, log_subscriber: nilEvents
The following events are instrumented by the instrumentation plugin:
upload.shrine
The upload.shrine event is logged on Shrine#upload, and contains the
following payload:
| Key | Description |
|---|---|
:storage | The storage identifier |
:location | The location of the uploaded file |
:io | The uploaded IO object |
:upload_options | Any upload options that were specified |
:metadata | Metadata extracted during upload |
:options | Any additional uploader options |
:uploader | The uploader class that sent the event |
download.shrine
The download.shrine event is logged on UploadedFile#stream (which includes
UploadedFile#download), and contains the following payload:
| Key | Description |
|---|---|
:storage | The storage identifier |
:location | The location of the uploaded file |
:download_options | Any download options that were specified |
:uploader | The uploader class that sent the event |
open.shrine
The download.shrine event is logged on UploadedFile#open or when uploaded
file is implicitly opened on calling an IO method.
| Key | Description |
|---|---|
:storage | The storage identifier |
:location | The location of the uploaded file |
:download_options | Any download options that were specified |
:uploader | The uploader class that sent the event |
exists.shrine
The exists.shrine event is logged on UploadedFile#exists?, and contains the
following payload:
| Key | Description |
|---|---|
:storage | The storage identifier |
:location | The location of the uploaded file |
:uploader | The uploader class that sent the event |
delete.shrine
The delete.shrine event is logged on UploadedFile#delete, and contains the
following payload:
| Key | Description |
|---|---|
:storage | The storage identifier |
:location | The location of the uploaded file |
:uploader | The uploader class that sent the event |
metadata.shrine
The metadata.shrine event is logged on Shrine#upload, and contains the
following payload:
| Key | Description |
|---|---|
:storage | The storage identifier |
:io | The uploaded IO object |
:options | Any options sent to the uploader |
:uploader | The uploader class that sent the event |
API
The instrumentation plugin adds Shrine.instrument and Shrine.subscribe
methods:
# sends a `my_event.shrine` event to the notifications component
Shrine.instrument(:my_event, { foo: "bar" }) do
# do work
end# subscribes to `my_event.shrine` events on the notifications component
Shrine.subscribe(:my_event) do |event|
event.name #=> :my_event
event.payload #=> { foo: "bar", uploader: Shrine }
event[:foo] #=> "bar"
event.duration #=> 15 (in milliseconds)
end