Class: OpenObserve::Dashboards
- Includes:
- DirectorySource
- Defined in:
- lib/openobserve/dashboards.rb
Overview
Dashboards, and the idempotent directory synchronisation deploys are built on.
Reads go through Resource#raw, and here the reason is not merely theoretical:
Api::Api::Dashboards pins type: Api::Models::Dashboard, a model that is wrong twice
over. OpenObserve answers these routes with a version envelope (hash, updatedAt,
version, v1…v8) rather than a flat dashboard, and the model declares none of it —
so a real dashboard came back with no panels at all.
The request direction needs no such care: the transport passes a plain Hash through verbatim, so a v5 document reaches OpenObserve byte for byte.
Idempotence
#sync keys on the exact title, because OpenObserve assigns dashboard ids itself
and ignores any dashboardId a payload carries — a file cannot claim an identity.
The consequence is worth stating plainly: renaming a dashboard in the OpenObserve UI
orphans it, and the next synchronisation recreates the original title alongside it.
Nothing is ever deleted here, so recovering from that is a manual act.
Constant Summary collapse
- DEFAULT_FOLDER =
The folder used when the caller names none. OpenObserve itself falls back to this folder on create, and
updaterefuses to run without one, so it is pinned rather than left to the server. Deliberately not Client#folder: that one designates an alert folder, and OpenObserve scopes folders per object type. 'default'- DEFAULT_PATTERN =
Files #sync picks up. Matches the
*.oo.jsonconvention as well as plain*.json. '*.json'
Constants inherited from Resource
Instance Method Summary collapse
-
#create(definition, folder: DEFAULT_FOLDER) ⇒ OpenObserve::Dashboard
The created dashboard, id included.
- #delete(id, folder: DEFAULT_FOLDER) ⇒ void
-
#find_by_title(title, folder: DEFAULT_FOLDER) ⇒ OpenObserve::Dashboard?
The one dashboard whose title matches exactly, case included.
- #get(id, folder: DEFAULT_FOLDER) ⇒ OpenObserve::Dashboard
- #list(folder: DEFAULT_FOLDER, title: nil, page_size: nil) ⇒ Array<OpenObserve::Dashboard>
-
#sync(directory, folder: DEFAULT_FOLDER, pattern: DEFAULT_PATTERN) ⇒ Hash{Symbol=>Array<String>}
Push a directory of dashboard documents into OpenObserve, creating what is missing and overwriting what is already there.
- #update(id, definition, revision:, folder: DEFAULT_FOLDER) ⇒ OpenObserve::Dashboard
Methods included from DirectorySource
Methods inherited from Resource
Constructor Details
This class inherits a constructor from OpenObserve::Resource
Instance Method Details
#create(definition, folder: DEFAULT_FOLDER) ⇒ OpenObserve::Dashboard
Returns the created dashboard, id included.
72 73 74 75 76 |
# File 'lib/openobserve/dashboards.rb', line 72 def create(definition, folder: DEFAULT_FOLDER) Dashboard.from( call { raw(:POST, collection_path, query: { 'folder' => folder }, body: definition) } ) end |
#delete(id, folder: DEFAULT_FOLDER) ⇒ void
This method returns an undefined value.
96 97 98 99 |
# File 'lib/openobserve/dashboards.rb', line 96 def delete(id, folder: DEFAULT_FOLDER) call { raw(:DELETE, member_path(id), query: { 'folder' => folder }) } nil end |
#find_by_title(title, folder: DEFAULT_FOLDER) ⇒ OpenObserve::Dashboard?
The one dashboard whose title matches exactly, case included.
53 54 55 56 57 |
# File 'lib/openobserve/dashboards.rb', line 53 def find_by_title(title, folder: DEFAULT_FOLDER) exact = list(folder: folder, title: title).select { |dashboard| dashboard.title == title } unique(exact, title) end |
#get(id, folder: DEFAULT_FOLDER) ⇒ OpenObserve::Dashboard
63 64 65 66 67 |
# File 'lib/openobserve/dashboards.rb', line 63 def get(id, folder: DEFAULT_FOLDER) Dashboard.from( one('dashboard') { raw(:GET, member_path(id), query: { 'folder' => folder }) } ) end |
#list(folder: DEFAULT_FOLDER, title: nil, page_size: nil) ⇒ Array<OpenObserve::Dashboard>
39 40 41 42 43 44 45 |
# File 'lib/openobserve/dashboards.rb', line 39 def list(folder: DEFAULT_FOLDER, title: nil, page_size: nil) payload = collection do raw(:GET, collection_path, query: { 'folder' => folder, 'title' => title, 'pageSize' => page_size }) end Array(payload && payload['dashboards']).map { |dashboard| Dashboard.from(dashboard) } end |
#sync(directory, folder: DEFAULT_FOLDER, pattern: DEFAULT_PATTERN) ⇒ Hash{Symbol=>Array<String>}
Push a directory of dashboard documents into OpenObserve, creating what is missing and overwriting what is already there. Safe to replay: a second run over an unchanged directory rewrites the same content and leaves the same set of dashboards.
Nothing is ever deleted — a dashboard the directory no longer describes stays put.
The whole folder is listed once, so the cost is one request plus one write per file, and the revision each write must echo back is taken from that listing.
121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/openobserve/dashboards.rb', line 121 def sync(directory, folder: DEFAULT_FOLDER, pattern: DEFAULT_PATTERN) definitions = read_definitions(directory, pattern, 'title', noun: 'dashboard') index = index_by_title(list(folder: folder)) result = { created: [], updated: [] } definitions.each do |title, definition| current = unique(index[title] || [], title) result[current ? :updated : :created] << title write(current, definition, folder: folder) end result end |
#update(id, definition, revision:, folder: DEFAULT_FOLDER) ⇒ OpenObserve::Dashboard
85 86 87 88 89 90 91 |
# File 'lib/openobserve/dashboards.rb', line 85 def update(id, definition, revision:, folder: DEFAULT_FOLDER) Dashboard.from( call do raw(:PUT, member_path(id), query: { 'folder' => folder, 'hash' => revision }, body: definition) end ) end |