Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a status dashboard #31

Merged
merged 8 commits into from
Jun 30, 2015
Merged

Conversation

blag
Copy link
Contributor

@blag blag commented Jun 17, 2015

Visual indications of overall and subsystem "good" status for quick and easy checking:
screen shot 2015-06-17 at 6 47 41 pm

Visual and textual hints of overall and subsystem "error" status to direct attention to failing subsystems and provide hints to view more failure information:
screen shot 2015-06-17 at 6 42 07 pm

Full error text and tracebacks rendered in modal windows to avoid cluttering the main table but still give useful failure information (a mocked-up version is shown here):
screen shot 2015-06-17 at 6 55 49 pm

Likely closes #11.

@landscape-bot
Copy link

Code Health
Repository health decreased by 1% when pulling 747941d on blag:add-status-dashboard into e443d84 on mwarkentin:master.

@landscape-bot
Copy link

Code Health
Code quality remained the same when pulling e2527d8 on blag:add-status-dashboard into e443d84 on mwarkentin:master.

@landscape-bot
Copy link

Code Health
Code quality remained the same when pulling ad80001 on blag:add-status-dashboard into e443d84 on mwarkentin:master.

@mwarkentin
Copy link
Owner

@blag could you put up a screenshot in the PR description? Thanks!

@blag
Copy link
Contributor Author

blag commented Jun 18, 2015

Done! :)

Working under the assumption that default templates are more guidelines than complete solutions, I made the default template fairly basic. However, I did add in Bootstrap 3 classes, and the modal windows are implemented with Bootstrap. The page should gracefully degrade if a site doesn't use Bootstrap, and although it won't look pretty, it should still be functional.

@landscape-bot
Copy link

Code Health
Code quality remained the same when pulling 50d498a on blag:add-status-dashboard into e443d84 on mwarkentin:master.

@mwarkentin
Copy link
Owner

First of all, I'd just like to say "Thank you!" for this PR - looks great!

I'm wondering if it doesn't make more sense to make the template + styling + behaviour (modals for tracebacks, etc.) more standalone, rather than relying on Bootstrap and falling back to no styling.

Seems like it would be pretty straightforward to build out the standalone template, and just load Bootstrap (or something smaller like PureCSS / min) from a CDN?

While Bootstrap is pretty common, I wouldn't be surprised if there are a lot of people not using it, or still using Bootstrap 2. This is also a tool meant for internal teams, so a bit of extra time to download another css framework on first page load doesn't seem ridiculous.

Thoughts?

@blag
Copy link
Contributor Author

blag commented Jun 18, 2015

Of the Django apps that I've taken a look at, Bootstrap 3 seems to be the most commonly supported framework. That doesn't mean that older versions of those apps aren't being run, just that most apps have updated their templates to assume Bootstrap 3.

I would not be surprised to hear about internal tools using no framework, Bootstrap 2, Foundations, or something else, but I think the thing to keep in mind is that this template isn't very complicated and - being a Django1 template - is easily overridable. That basically means that we are really only discussing what to support by default.

For this PR, I wanted something that looks decently pretty "out of the box" with a minimum of fuss but still worked without dependencies, and Bootstrap 3 filled that role perfectly.

So to be perfectly clear: I don't see it being worth it to switch to something else.

1 Meaning awesome.

@mwarkentin
Copy link
Owner

I think I'd prefer to make the dashboard functional / pretty out of the box, and I think that's easiest to do my making the dashboard template standalone, rather than extending a base template from the Django project. Slightly selfishly, we don't use Bootstrap 3 at work, and I'd prefer not to have to override the template for every project we use django-watchman on.. 😄

I checked out your branch and poked around at it a bit:

  • Replaced extends with a full html template
  • Include bootstrap css / js from a CDN
  • Moved overall status line out into it's own header, colour coded, with an icon
  • Switched to colour coding the entire check row, rather than just the type / status columns
  • Added div.container to center the content

Here's the code:

{% load i18n %}

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
        <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    </head>
    <body>
        {% block content %}
        <div class="container">
            <h2>{% trans 'System Status' %}</h2>
            <h3 class="{% if overall_status == 'OK' %}text-success{% else %}text-danger{% endif %}">
                {% if overall_status == 'OK' %}
                    <span class="glyphicon glyphicon-ok"></span> {% trans 'All systems up and running!' %}
                {% else %}
                    <span class="glyphicon glyphicon-remove"></span> {% trans 'WARNING - Some systems down!' %}
                {% endif %}
            </h3>
            <small></small>

            <table class="table table-bordered table-hover">
                <thead>
                <tr>
                    <th>{% trans 'Type' %}</th>
                    <th>{% trans 'Name' %}</th>
                    <th>{% trans 'Status' %}</th>
                </tr>
                </thead>
                <tbody>
                {% for type in checks %}
                {% for thing in type.statuses %}
                <tr class="{% if type.overall_status == 'OK' %}success{% else %}danger{% endif %}">
                    <td>{{ type.type|title }}</td>
                    <td>{{ thing.name|title }}</td>

                    {% if thing.status == 'OK' %}
                    <td class="success">{% trans 'OK' %}</td>

                    {% else %}
                    <td class="danger">
                        <button type="button" class="btn btn-danger" data-toggle="modal" data-target="#{{ type.type }}-{{ thing.name }}">{% trans 'ERROR!' %}</button>

                        <div class="modal fade" id="{{ type.type }}-{{ thing.name }}" tabindex="-1" role="dialog" aria-labelledby="{{ type.type }}-{{ thing.name }}-title">
                            <div class="modal-dialog" role="document">
                                <div class="modal-content">
                                    <div class="modal-header">
                                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                                        <h4 class="modal-title" id="{{ type.type }}-{{ thing.name }}-title">{{ type.type|title }} - {{ thing.name|title }}</h4>
                                    </div><!-- class="modal-header" -->
                                    <div class="modal-body">
                                        <h4><pre>{{ thing.error }}</pre></h4>
                                        <pre>{{ thing.traceback }}</pre>
                                    </div><!-- class="model-body" -->
                                    <div class="modal-footer">
                                        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                                    </div><!-- class="modal-footer" -->
                                </div>
                            </div>
                        </div>
                    </td>
                    {% endif %}{# thing.status == 'OK' #}

                </tr>
                {% endfor %}{# for thing in type.statuses #}
                {% empty %}
                <tr>
                    <td colspan="3">{% trans 'No checks indicated.' %}</td>
                </tr>
                {% endfor %}{# for type in checks #}
                </tbody>
            </table>

            {% if overall_status != 'OK' %}<span class="pull-right"><small>{% trans 'Click an error button to see the full traceback' %}</small></span>{% endif %}{# overall_status != 'OK' #}
        </div>
        {% endblock %}{# status_content #}
    </body>
</html>

What do you think about doing something like that?

@blag
Copy link
Contributor Author

blag commented Jun 19, 2015

That looks great!

The only change I would make is to use the alert glyphicon rather than the remove glyphicon to indicate non-OK system status, because it's semantics are closer to the intent.

@mwarkentin
Copy link
Owner

alert works for me! Did you want to update your PR with the new template code? I'm not sure how to submit code back to your branch. 😄

@blag
Copy link
Contributor Author

blag commented Jun 20, 2015

Sure, I can do that! It will very likely be sometime later this weekend though.

@mwarkentin
Copy link
Owner

No prob. :)

…ry and Bootstrap 3, and use the 'alert' (not 'remove') glyphicon
@landscape-bot
Copy link

Code Health
Code quality remained the same when pulling e3fe57b on blag:add-status-dashboard into e443d84 on mwarkentin:master.

# Example: [{'default': {'ok': True}}]
statuses = []

for a in _check[_type]:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use something a little more descriptive than a here? Maybe result?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doh! Yes.

@mwarkentin
Copy link
Owner

Think it's worth adding a few django TestClient tests for this view?

@mwarkentin
Copy link
Owner

@blag Sorry for the delay, finished my first full pass through the code. Hopefully my suggestions make sense.. if not, let me know. 😄

@blag
Copy link
Contributor Author

blag commented Jun 23, 2015

TestClient cases wouldn't be a bad idea, but as far as I know the only things we could easily/realistically test is the HTTP 200 response status.

@mwarkentin
Copy link
Owner

Yeah, I've also seen tests to verify that the correct template is loaded. Not sure if that really adds much value here though.. maybe more so if the template is dynamic.

@landscape-bot
Copy link

Code Health
Code quality remained the same when pulling da35841 on blag:add-status-dashboard into e443d84 on mwarkentin:master.

<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently we should probably just hardcode these to https://: http://www.paulirish.com/2010/the-protocol-relative-url/

Now that SSL is encouraged for everyone and doesn’t have performance concerns, this technique is now an anti-pattern. If the asset you need is available on SSL, then always use the https:// asset.

Allowing the snippet to request over HTTP opens the door for attacks like the recent Github Man-on-the-side attack. It’s always safe to request HTTPS assets even if your site is on HTTP, however the reverse is not true.

@mwarkentin
Copy link
Owner

Ok, a couple of last comments on another pass through, and then I think I'm good to go with this PR!

@landscape-bot
Copy link

Code Health
Code quality remained the same when pulling 6179379 on blag:add-status-dashboard into e443d84 on mwarkentin:master.

@mwarkentin
Copy link
Owner

@blag Hoping to get these merged in tomorrow.

@blag
Copy link
Contributor Author

blag commented Jun 30, 2015

Cool! I can be on standby today to fix any last minute issues that may arise. The odd Travis issues I experienced have made me just a tiny bit worried and skeptical that it's going to go perfectly.

@mwarkentin
Copy link
Owner

That looks like it was a network failure: ConnectionResetError: [Errno 104] Connection reset by peer

All of the builds passed except for one while installing pip packages, which also leads me to believe it was a temporary issues:

@mwarkentin mwarkentin merged commit 6179379 into mwarkentin:master Jun 30, 2015
@blag
Copy link
Contributor Author

blag commented Jul 2, 2015

Now that these are merged in, can you cut a new release on PyPI? I'd like to remove my vendored version of watchman.

Thanks for all of your work reviewing/commenting/advising! 😃

@mwarkentin
Copy link
Owner

@blag Hopefully soon, doing some testing on master with all of the PRs merged together.

@mwarkentin
Copy link
Owner

@blag I've pushed up a 0.6.0a0 release from master, if you're ok with using that.

@mwarkentin
Copy link
Owner

@blag Oh, also, would you like to be referred to as blag in AUTHORS.rst, or prefer to have your real name? Thanks!

@mwarkentin
Copy link
Owner

@blag I just opened a PR which lets you skip/check specific checks on the dashboard as well: #34

Can you take a look?

@mwarkentin
Copy link
Owner

@blag Ok, released 0.6.0 final, with a few extra tweaks (you can pass get params to the dashboard view to customize the checks like you can with the json view, and I added a X-Watchman-Version header to the responses for both views).

@blag
Copy link
Contributor Author

blag commented Jul 2, 2015

Thanks for asking about my name preferences - what you have now is fine. If I really cared I would have made that part of my PR. 😉

I took a look at #34, and it looked good to me, aside from the (truly) tiny defense-in-depth violation I pointed out.

Thanks for releasing 0.6.0!

I will probably work on #5 and #8 at some point "real soon now", because I will need them for a project.

@mwarkentin
Copy link
Owner

@blag No problem. That'd be awesome to get the ES / celery checks built - let me know if you have any questions and I can try to help you out.

@blag blag deleted the add-status-dashboard branch February 2, 2016 00:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Status dashboard
3 participants