Code Monkey home page Code Monkey logo

kennel's Introduction

Manage Datadog Monitors / Dashboards / Slos as code

  • DRY, searchable, audited, documented
  • Changes are PR reviewed and applied on merge
  • Updating shows diff before applying
  • Automated import of existing resources
  • Resources are grouped into projects that belong to teams and inherit tags
  • No copy-pasting of ids to create new resources
  • Automated cleanup when removing code
  • Helpers for automating common tasks

Applying changes

Example code

# teams/foo.rb
module Teams
  class Foo < Kennel::Models::Team
    defaults(mention: -> { "@slack-my-team" })
  end
end

# projects/bar.rb
class Bar < Kennel::Models::Project
  defaults(
    team: -> { Teams::Foo.new }, # use mention and tags from the team
    tags: -> { super() + ["project:bar"] }, # unique tag for all project components
    parts: -> {
      [
        Kennel::Models::Monitor.new(
          self, # the current project
          type: -> { "query alert" },
          kennel_id: -> { "load-too-high" }, # pick a unique name
          name: -> { "Foobar Load too high" }, # nice descriptive name that will show up in alerts and emails
          message: -> {
            <<~TEXT
              This is bad!
              #{super()} # inserts mention from team
            TEXT
          },
          query: -> { "avg(last_5m):avg:system.load.5{hostgroup:api} by {pod} > #{critical}" },
          critical: -> { 20 }
        )
      ]
    }
  )
end

Installation

  • create a new private kennel repo for your organization (do not fork this repo)
  • use the template folder as starting point:
    git clone [email protected]:your-org/kennel.git
    git clone [email protected]:grosser/kennel.git seed
    mv seed/template/* kennel/
    cd kennel && git add . && git commit -m 'initial'
  • add a basic projects and teams so others can copy-paste to get started
  • setup CI build for your repo (travis and Github Actions supported)
  • uncomment .travis.yml section for datadog updates on merge (TODO: example setup for Github Actions)
  • follow Setup in your repos Readme.md

Structure

  • projects/ monitors/dashboards/etc scoped by project
  • teams/ team definitions
  • parts/ monitors/dashboards/etc that are used by multiple projects
  • generated/ projects as json, to show current state and proposed changes in PRs

About the models

Kennel provides several classes which act as models for different purposes:

  • Kennel::Models::Dashboard, Kennel::Models::Monitor, Kennel::Models::Slo, Kennel::Models::SyntheticTest; these models represent the various Datadog objects
  • Kennel::Models::Project; a container for a collection of Datadog objects
  • Kennel::Models::Team; provides defaults and values (e.g. tags, mentions) for the other models.

After loading all the *.rb files under projects/, Kennel's starting point is to find all the subclasses of Kennel::Models::Project, and for each one, create an instance of that subclass (via .new) and then call #parts on that instance. parts should return a collection of the Datadog-objects (Dashboard / Monitor / etc).

Model Settings

Each of the models defines various settings; for example, a Monitor has name, message, type, query, tags, and many more.

When defining a subclass of a model, one can use defaults to provide default values for those settings:

class MyMonitor < Kennel::Models::Monitor
  defaults(
    name: "Error rate",
    type: "query alert",
    critical: 5.0,
    query: -> {
      "some datadog metric expression > #{critical}"
    },
    # ...
  )
end

This is equivalent to defining instance methods of those names, which return those values:

class MyMonitor < Kennel::Models::Monitor
  def name
    "Error rate"
  end

  def type
    "query alert"
  end

  def critical
    5.0
  end

  def query
    "some datadog metric expression > #{critical}"
  end
end

except that defaults will complain if you try to use a setting name which doesn't exist. Note also that you can use either plain values (critical: 5.0), or procs (query: -> { ... }). Using a plain value is equivalent to using a proc which returns that same value; use whichever suits you best.

When you instantiate a model class, you can pass settings in the constructor, after the project:

project = Kennel::Models::Project.new
my_monitor = MyMonitor.new(
  project,
  critical: 10.0,
  message: -> {
    <<~MESSAGE
      Something bad is happening and you should be worried.

      #{super()}
    MESSAGE
  },
)

This works just like defaults (it checks the setting names, and it accepts either plain values or procs), but it applies just to this instance of the class, rather than to the class as a whole (i.e. it defines singleton methods, rather than instance methods).

Most of the examples in this Readme use the proc syntax (critical: -> { 5.0 }) but for simple constants you may prefer to use the plain syntax (critical: 5.0).

Workflows

Adding a team

  • mention is used for all team monitors via super()
  • renotify_interval is used for all team monitors (defaults to 0 / off)
  • tags is used for all team monitors/dashboards (defaults to team:<team-name>)
# teams/my_team.rb
module Teams
  class MyTeam < Kennel::Models::Team
    defaults(
      mention: -> { "@slack-my-team" }
    )
  end
end

Adding a new monitor

Updating an existing monitor

  • use datadog monitor UI to find a monitor
  • run URL='https://app.datadoghq.com/monitors/123' bundle exec rake kennel:import and copy the output
  • find or create a project in projects/
  • add the monitor to parts: [ list, for example:
# projects/my_project.rb
class MyProject < Kennel::Models::Project
  defaults(
    team: -> { Teams::MyTeam.new }, # use existing team or create new one in teams/
    parts: -> {
      [
        Kennel::Models::Monitor.new(
          self,
          id: -> { 123456 }, # id from datadog url, not necessary when creating a new monitor
          type: -> { "query alert" },
          kennel_id: -> { "load-too-high" }, # make up a unique name
          name: -> { "Foobar Load too high" }, # nice descriptive name that will show up in alerts and emails
          message: -> {
            # Explain what behavior to expect and how to fix the cause
            # Use #{super()} to add team notifications.
            <<~TEXT
              Foobar will be slow and that could cause Barfoo to go down.
              Add capacity or debug why it is suddenly slow.
              #{super()}
            TEXT
          },
          query: -> { "avg(last_5m):avg:system.load.5{hostgroup:api} by {pod} > #{critical}" }, # replace actual value with #{critical} to keep them in sync
          critical: -> { 20 }
        )
      ]
    }
  )
end
  • run PROJECT=my_project bundle exec rake plan, an Update to the existing monitor should be shown (not Create / Delete)
  • alternatively: bundle exec rake generate to only locally update the generated json files
  • review changes then git commit
  • make a PR ... get reviewed ... merge
  • datadog is updated by CI

Deleting

Remove the code that created the resource. The next update will delete it (see above for PR workflow).

Adding a new dashboard

Updating an existing dashboard

  • go to datadog dashboard UI and click on New Dashboard to find a dashboard
  • run URL='https://app.datadoghq.com/dashboard/bet-foo-bar' bundle exec rake kennel:import and copy the output
  • find or create a project in projects/
  • add a dashboard to parts: [ list, for example:
class MyProject < Kennel::Models::Project
  defaults(
    team: -> { Teams::MyTeam.new }, # use existing team or create new one in teams/
    parts: -> {
      [
        Kennel::Models::Dashboard.new(
          self,
          id: -> { "abc-def-ghi" }, # id from datadog url, not needed when creating a new dashboard
          title: -> { "My Dashboard" },
          description: -> { "Overview of foobar" },
          template_variables: -> { ["environment"] }, # see https://docs.datadoghq.com/api/?lang=ruby#timeboards
          kennel_id: -> { "overview-dashboard" }, # make up a unique name
          layout_type: -> { "ordered" },
          definitions: -> {
            [ # An array or arrays, each one is a graph in the dashboard, alternatively a hash for finer control
              [
                # title, viz, type, query, edit an existing graph and see the json definition
                "Graph name", "timeseries", "area", "sum:mystats.foobar{$environment}"
              ],
              [
                # queries can be an Array as well, this will generate multiple requests
                # for a single graph
                "Graph name", "timeseries", "area", ["sum:mystats.foobar{$environment}", "sum:mystats.success{$environment}"],
                # add events too ...
                events: [{q: "tags:foobar,deploy", tags_execution: "and"}]
              ]
            ]
          }
        )
      ]
    }
  )
end

Updating existing resources with id

Setting id makes kennel take over a manually created datadog resource. When manually creating to import, it is best to remove the id and delete the manually created resource.

When an id is set and the original resource is deleted, kennel will fail to update, removing the id will cause kennel to create a new resource in datadog.

Organizing projects with many resources

When project files get too long, this structure can keep things bite-sized.

# projects/project_a/base.rb
module ProjectA
  class Base < Kennel::Models::Project
    defaults(
      kennel_id: -> { "project_a" },
      parts: -> {
        [
          Monitors::FooAlert.new(self),
          ...
        ]
      }
      ...

# projects/project_a/monitors/foo_alert.rb
module ProjectA
  module Monitors
    class FooAlert < Kennel::Models::Monitor
      ...

Updating a single project or resource

  • Use PROJECT=<kennel_id> for single project:

    Use the projects kennel_id (and if none is set then snake_case of the class name including modules) to refer to the project. For example for class ProjectA use PROJECT=project_a but for Foo::ProjectA use foo_project_a.

  • Use TRACKING_ID=<project-kennel_id>:<resource-kennel_id> for single resource:

    Use the project kennel_id and the resources kennel_id, for example class ProjectA and FooAlert would give project_a:foo_alert.

Skipping validations

Some validations might be too strict for your usecase or just wrong, please open an issue and to unblock use the validate: -> { false } option.

Linking resources with kennel_id

Link resources with their kennel_id in the format project kennel_id + : + resource kennel_id, this should be used to create dependent resources like monitor + slos, so they can be created in a single update and can be re-created if any of them is deleted.

Resource Type Syntax
Dashboard uptime monitor: {id: "foo:bar"}
Dashboard alert_graph alert_id: "foo:bar"
Dashboard slo slo_id: "foo:bar"
Dashboard timeseries queries: [{ data_source: "slo", slo_id: "foo:bar" }]
Monitor composite query: -> { "%{foo:bar} && %{foo:baz}" }
Monitor slo alert query: -> { "error_budget(\"%{foo:bar}\").over(\"7d\") > 123.0" }
Slo monitor monitor_ids: -> ["foo:bar"]

Debugging changes locally

  • rebase on updated master to not undo other changes
  • figure out project name by converting the class name to snake_case
  • run PROJECT=foo bundle exec rake kennel:update_datadog to test changes for a single project (monitors: remove mentions while debugging to avoid alert spam)
    • use PROJECT=foo,bar,... for multiple projects

Reuse

Add to parts/<folder>.

module Monitors
  class LoadTooHigh < Kennel::Models::Monitor
    defaults(
      name: -> { "#{project.name} load too high" },
      message: -> { "Shut it down!" },
      type: -> { "query alert" },
      query: -> { "avg(last_5m):avg:system.load.5{hostgroup:#{project.kennel_id}} by {pod} > #{critical}" }
    )
  end
end

Reuse it in multiple projects.

class Database < Kennel::Models::Project
  defaults(
    team: -> { Kennel::Models::Team.new(mention: -> { '@slack-foo' }, kennel_id: -> { 'foo' }) },
    parts: -> { [Monitors::LoadTooHigh.new(self, critical: -> { 13 })] }
  )
end

Helpers

Listing un-muted alerts

Run rake kennel:alerts TAG=service:my-service to see all un-muted alerts for a given datadog monitor tag.

Validating mentions work

rake kennel:validate_mentions should run as part of CI

Grepping through all of datadog

rake kennel:dump > tmp/dump
cat tmp/dump | grep foo

focus on a single type: TYPE=monitors

Show full resources or just their urls by pattern:

rake kennel:dump_grep DUMP=tmp/dump PATTERN=foo URLS=true
https://foo.datadog.com/dasboard/123
https://foo.datadog.com/monitor/123

Find all monitors with No-Data

rake kennel:nodata TAG=team:foo

Finding the tracking id of a resource

When trying to link resources together, this avoids having to go through datadog UI.

rake kennel:tracking_id ID=123 RESOURCE=monitor

Development

Benchmarking

  • Setting FORCE_GET_CACHE=true will cache all get requests, which makes benchmarking improvements more reliable.
  • Setting STORE=false will make rake plan not update the files on disk and save a bit of time

Integration testing

rake play
cd template
rake plan

Then make changes to play around, do not commit changes and make sure to revert with a rake kennel:update_datadog after deleting everything.

To make changes via the UI, make a new free datadog account and use it's credentials instead.

Author

Michael Grosser
[email protected]
License: MIT
CI

kennel's People

Contributors

adammw avatar amitizle avatar brianburnszd avatar codygill avatar dadah89 avatar dannytranlx avatar eatwithforks avatar gabetax avatar grosser avatar henders avatar kaarolch avatar mbigornia avatar mesge avatar petern-sc avatar rbayerl avatar redhotpenguin avatar smo921 avatar stewi2 avatar tancnle avatar tang8330 avatar th11 avatar timbertson avatar trungnn avatar uthark avatar waichee avatar william-tio avatar zdrve avatar zendesk-sebastien-lambert avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kennel's Issues

Thoughts

Hello,
We're interested in using kennel as the basis of our Monitoring as Code project. Our use case is slightly different than how kennel is written.

We'd like to be able to use kennel as the starting point to create our dashboards, but we don't want our developers to be limited to updating them in code. We'd like developers to be able to update the dashboards themselves within the Datadog UI, and then use kennel to grab the changed dashboard and commit the changes into version control.

I believe this would require some changes to kennel to do well. For instance, we want the ability to add a dashboard using kennel, but not update ones that haven't been pulled into version control yet. We'd also like to be able to import existing stuff by kennel_id to find the datadog id.

As I go down the path of building this out, I wanted to know if the changes I make would be welcome to kennel or if you would like to keep this functionality out because it violates what you're trying to build.

kennel should not crash if an import "id" cannot be found

Instead it should just ignore the ID and continuing creating a new object, perhaps with a warning.

This would make kennel more stable and eliminate one of the more common ways that master breaks, especially because right now when this happens it's not a breakage as a result of a recent commit.

PROJECT filter & tracking field error

I've recently got an error when using the PROJECT filter:

Updates with PROJECT= filter should not update message/description of resources with a set id:, since this makes them get deleted by a full update.
Remove the id: to test them out, which will result in a copy being created and later deleted.

I'm having a hard time to figure out why you added this safeguard.

The current implementation does not offer more details.

kennel/lib/kennel/syncer.rb

Lines 181 to 188 in f032de3

def block_irreversible_partial_updates
return unless @project_filter
return if @update.none? { |_, e, _, diff| e.id && diff.any? { |_, field| TRACKING_FIELDS.include?(field.to_sym) } }
raise <<~TEXT
Updates with PROJECT= filter should not update #{TRACKING_FIELDS.join("/")} of resources with a set `id:`, since this makes them get deleted by a full update.
Remove the `id:` to test them out, which will result in a copy being created and later deleted.
TEXT
end

Same for the initial PR that introduced this safeguard (#43): I still don't get it 🤔

Could you explain why this safeguard exists?

A bit more about how I intend to use the PROJECT filter

For simplicity's sake, I want to be able to test a pull request and run a kennel:update_datadog on a specific branch.

Since the repository is shared among our company developers' community, using PROJECT would allow us to minimize the risk of updating/deleting Datadog resources on different PRs.

Example

  • Developer A is on branch new-product-a-observability which creates a monitor
  • Developer B is on branch small-fix-on-screenboard-b which fixes a few typos on an existing screenboard

Scenario:

  1. Developer A runs kennel:update_datadog on its branch new-product-a-observability and it creates its monitor
  2. Developer A shares the monitor URL in its PR for showcase purposes & to ease their peer's review
  3. Developer B runs kennel:update_datadog on its branch small-fix-on-screenboard-b to check a few tings
  4. Developer A got their monitor deleted 🤷‍♂️

This is why using the PROJECT filter would allow to only update a specific project and not touch anything else.


I may not have the right mindset, though. Let me know if you see a better way to handle this kind of workflow or if kennel is not intended to be used this way.

Anyway, thank you in advance for your help and nice work on this tool!

Make imports dryer

PR welcome ... also pretty simple

  • simplify template_variables to produce arrays
  • remove empty conditional_formats
  • remove default style

Composite monitors fail the "plan" phase.

While creating a composite monitor, it is not possible to run the Plan phase.
This is because it tries to use the "critical" value. - which is usually not defined in a composite monitor (it uses Boolean logic between other monitors to decide when to trigger each level of alerts).

It should be enough if we define the "Critical" property as nil in case the monitor is a composite one (so it won't need to be explicitly dealt with in the rb files).

Validation for DataDog alias metadata

I came across this use case when running kennel:plan on one of my project.

Symbol validation for Optional fails on DataDog alias metadata

metadata: {    
  "autosmooth(avg:some_metric)" => {
    alias: "With Labels"
  }
}

The related validation logic can be found here

def validate_json(data)

Few thoughts

  1. Downgrade this validation to warning and still proceed with running kennel:plan
  2. Exclude this rule for metadata

Crash when trying to report Kennel API error

https://zendesk.slack.com/archives/C81T33XTK/p1692346298884879

[129, 138] in /Users/revans/git/github.com/grosser/kennel/lib/kennel/api.rb
   129:         if !response.success? && (response.status != 404 || !ignore_404)
   130:           message = +"Error #{response.status} during #{method.upcase} #{path}\n"
   131:           message << "request:\n#{JSON.pretty_generate(body)}\nresponse:\n" if body
   132:           require 'byebug'
   133:           byebug
=> 134:           message << response.body
   135:           raise message
   136:         end
   137: 
   138:         if response.body.empty?
(byebug) message.encoding
#<Encoding:UTF-8>
(byebug) response.body.encoding
#<Encoding:ASCII-8BIT>
(byebug) message + response.body
*** Encoding::CompatibilityError Exception: incompatible character encodings: UTF-8 and ASCII-8BIT

nil
(byebug) message + String.new(response.body, encoding: message.encoding)
"Error 400 during POST /api/v1/monitor\nrequest:\n{\n  \"name\": \"text-matching-ml-service - (Production) Error Budget Alert on SLO🔒\",\n  \"type\": \"slo alert\",\n  \"query\": \"error_budget(\\\"57f99d0335815223a57b7f978fe62d33\\\").o (etc etc etc)



Group and Note Widgets

It would be great if we could use the "Group" and "Note" widgets on our dashboards. They help organise and explain more complex dashboards.

error
Kennel::Models::Base::ValidationError: riak:riak-disk-volume-predict query interval was , but must be one of 1m, 5m, 10m, 15m, 30m, 1h, 2h, 4h, 1d

Error:
error
Kennel::Models::Base::ValidationError: riak:riak-disk-volume-predict query interval was , but must be one of 1m, 5m, 10m, 15m, 30m, 1h, 2h, 4h, 1d

Imported a forecast based monitor
the query is
"query": "min(next_3mo):forecast(min:system.disk.free{hostgroup:riak,environment:production,device:/var/lib/riak} by {pod}, 'linear', 1, interval='120m', history='3mo', model='reactive') <= 0.0",

Was trying intervals listed and many other things...
It seems the parsing is somehow broken not even looking at that parameter correctly...
(plus probably need to add more timing options or having a less strict test?)

By query is projects/riak.rb/riak-disk-volume-predict
but noticed it gets the same thing for projects//container-scanner/monitors/container_scanner.rb/container-scanner-sqs-queue-is-projected-to-back-up

p.s.s. There are a few validate: -> { false } and 0 issues here... (me reading doc.. )

"Duplicate of an existing monitor_id:..." should cause the syncer to restart

The above error seems to be the result of a race condition of some kind (I can't say with complete confidence yet what's happening). Very often, it seems that the monitor ID it reports is effectively exactly the same one that it's trying to create (i.e. same kennel tracking id).

If we see the "duplicate of an existing monitor" error, then we should restart the syncer update from the top – but only do this once, to avoid looping.

Kennel doesn't seem to support Sentry queries

image

Commands (output from rake kennel:update_datadog)

rake aborted!
Error 400 during PUT /api/v1/monitor

response:
{"errors":["The value provided for parameter 'query' is invalid"]}

"Deep" importing

Feature suggestion.

Some kind of recursive-import mechanism.

Example: a dashboard which has a widget which shows an SLO (let's assume none of this is in Kennel yet). If you import the dashboard, the widget comes with it, but it references the SLO via a datadog id, and the SLO remains unimported. It would be nice to have some kind of mechanism to make the importing of related objects, and ideally the wiring together by kennel IDs, easier.

Can't resolve ID of not-yet-adopted item

Example:

  • we have an SLO, which exists in datadog, but not in kennel
  • we prepare a PR to import that SLO into kennel
  • rake kennel:update_datadog PROJECT=my_project works, but doesn't add the tracking_id

This is all fine so far. But now comes the problem:

  • on the same PR, we add a widget to some dashboard, with slo_id: "my_project:my_new_slo"
  • rake kennel:update_datadog PROJECT=my_project fails, saying it can't resolve my_project:my_new_slo.

Very hacky fix:

diff --git a/lib/kennel/syncer.rb b/lib/kennel/syncer.rb
index fec037e..82eb87c 100644
--- a/lib/kennel/syncer.rb
+++ b/lib/kennel/syncer.rb
@@ -105,7 +105,15 @@ module Kennel
           # Refuse to "adopt" existing items into kennel while running with a filter (i.e. on a branch).
           # Without this, we'd adopt an item, then the next CI run would delete it
           # (instead of "unadopting" it).
-          e.add_tracking_id unless filter.filtering? && a.fetch(:tracking_id).nil?
+          if filter.filtering? && a.fetch(:tracking_id).nil?
+            # Eww!
+            a[:tracking_id] = e.tracking_id
+            resolver.add_actual([a])
+            a[:tracking_id] = nil
+          else
+            e.add_tracking_id
+          end
+
           id = a.fetch(:id)
           diff = e.diff(a)
           a[:id] = id

Missing groups ?

We're using Kennel to code our monitors and some of our dashboards. We noticed when importing some dashboards the groups are lost after we export them. Apparently there's no support for it, but it would be nice.
I wanted to ask if there's any plan to support groups (or if it's already implemented and I'm not aware of it). Otherwise, maybe we could create a pull request to incorporate it.

show_legend not working

There seems to be an issue with managing legends through kennel.

This widget should have a compact legend defined.
https://github.com/zendesk/kennel/blob/b1361608c9458f96cdb53d1bdec7e08eadd7d52d/projects/classic_attachments/dashboards/classic_attachments.rb#L585-L586

legend_layout: "horizontal",
show_legend: true,

Example widget on datadog : https://zendesk.datadoghq.com/dashboard/ewm-ejt-5qc/classic-attachments?fullscreen_end_ts=1682371724827&fullscreen_paused=false&fullscreen_section=overview&fullscreen_start_ts=1682357324827&fullscreen_widget=2219576726347122&from_ts=1682356956553&to_ts=1682371356553&live=true

Missing legend
image
image

I tried manually deleting the widget in the UI then doing a manual update via kennel, which worked initially but eventually reverted to no legend showing at some point after, presumably when a kennel PR merged and it ran an update.

1d interval not supported by Kennel, 24h interval not supported by Datadog

It looks like Datadog changed some of the interval syntax in their API. When I generate a new monitor via the UI with an evaluation period of 1 day, the query I get in the export is

"query": "sum(last_1d):min:...

When I execute this in Kennel, Kennel raises an error that my interval is invalid (see https://github.com/grosser/kennel/blob/master/lib/kennel/models/monitor.rb#L158-L163).

If I try to change this to 24h, Kennel doesn't raise an exception but Datadog chokes on the request:

Error 400 during PUT /api/v1/monitor/5315705
request:
...
"query": "sum(last_24h):min:...
...
response:
{"errors":["The value provided for parameter 'query' is invalid"]}

Guessing we need to allow 1d as a valid interval

Upgrading kennel gem isn't smooth

Running gem update on ruby-2.5.1 with rdoc-6.0.1 results in a fault.

Successfully installed kennel-1.28.3
Parsing documentation for kennel-1.28.3
Installing ri documentation for kennel-1.28.3
Installing darkfish documentation for kennel-1.28.3
ERROR:  While executing gem ... (RDoc::Error)
    error generating Kennel/Importer.html: no implicit conversion of nil into String (TypeError)

Workaround was to run the install without docs.

gem install kennel --no-rdoc --no-ri

Obsolete validation message for Monitor

After the change in #64 to require type for Monitor, the following validation message is no longer valid

Kennel::Models::Base::ValidationError: foo:bar-sli-monitor type 'metric alert' is deprecated, do not set type to use the default 'query alert'

My build failed because I used to not set type and rely on Kennel to default it to 'query alert'. I think the validation error message here should be updated.

SLO Summaries don't get imported

Datadog has changed around their SLO widgets work. Previously they operated as widgets of their own. They've now apparently gotten rid of the SLO widget and replaced them with the SLO Summary widget, now that they're treating SLO's as first class objects.

When you do an import of a dashboard that has SLO Summary widgets, they don't appear.

only load project that is requested

atm we always load all projects which takes a few seconds, would be nice to avoid that
autoload parts ... load only project when project.rb project/project.rb project_foo -> project/foo.rb exists

expected savings: ~1s (tried by hardcoding the correct require) (1.6s -> 0.5s to run generate)

we'd need to store a project -> file(s) map to make this work, maybe store after running generate
alternatively it could just support projects with the exact right path and fallback to all for the rest, but given our current messy project layout that would be almost nobody

Should the API always specify the subdomain?

I followed the readme and attempted to get Kennel setup.

Our datadog account only exists in us5.

I couldn't get bundle exec rake plan to pass without errors despite setting the subdomain.

I noticed here that we specify the subdomain as app overriding the environment variable because we have the ||= in Utils.

I started a branch and the specs passed. Testing it locally worked for me. Let me know if this is something that would be helpful or if I have misunderstood something.

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.