Skip to content
Snippets Groups Projects
Unverified Commit 9e4a14f4 authored by Daniel Higginbotham's avatar Daniel Higginbotham Committed by GitHub
Browse files

Debug helpers (#10845)

make it easier for users to report diagnostic info by adding it to the troubleshooting UI
parent d38794e1
No related branches found
No related tags found
No related merge requests found
......@@ -27,6 +27,9 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Information about your Metabase Installation:**
You can get this information by going to Admin -> Troubleshooting.
- Your browser and the version: (e.x. Chrome 52.1, Firefox 48.0, Safari 11.1, …)
- Your operating system: (e.x. OS X 10.10, Windows 10.1809, Ubuntu 16.04, …)
- Your databases: (e.x. MySQL, Postgres, MongoDB, …)
......
......@@ -11,7 +11,6 @@
[metabase.models.interface :as mi]
[toucan.db :as tdb]))
(defn init!
[]
(mbc/init!))
......
......@@ -34,6 +34,7 @@ import TaskModal from "metabase/admin/tasks/containers/TaskModal";
import JobInfoApp from "metabase/admin/tasks/containers/JobInfoApp";
import JobTriggersModal from "metabase/admin/tasks/containers/JobTriggersModal";
import Logs from "metabase/admin/tasks/containers/Logs";
import Help from "metabase/admin/tasks/containers/Help";
// People
import PeopleListingApp from "metabase/admin/people/containers/PeopleListingApp";
......@@ -109,7 +110,8 @@ const getRoutes = (store, IsAdmin) => (
title={t`Troubleshooting`}
component={TroubleshootingApp}
>
<IndexRedirect to="tasks" />
<IndexRedirect to="help" />
<Route path="help" component={Help} />
<Route path="tasks" component={TasksApp}>
<ModalRoute path=":taskId" modal={TaskModal} />
</Route>
......
import React, { Component } from "react";
import { t } from "ttag";
import _ from "underscore";
import { Box } from "grid-styled";
import AdminHeader from "metabase/components/AdminHeader";
import Code from "metabase/components/Code";
import CopyButton from "metabase/components/CopyButton";
import ExternalLink from "metabase/components/ExternalLink";
import { UtilApi } from "metabase/services";
import MetabaseSettings from "metabase/lib/settings";
function navigatorInfo() {
return _.pick(navigator, "language", "platform", "userAgent", "vendor");
}
const template = `**Describe the bug**
A clear and concise description of what the bug is.
**Logs**
Please include javascript console and server logs around the time this bug occurred. For information about how to get these, consult our [bug troubleshooting guide](https://metabase.com/docs/latest/troubleshooting-guide/bugs.html)
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Severity**
How severe an issue is this bug to you? Is this annoying, blocking some users, blocking an upgrade or blocking your usage of Metabase entirely?
Note: the more honest and specific you are here the more we will take you seriously.
**Additional context**
Add any other context about the problem here.
**Metabase Diagnostic Info**
`;
function githubIssueLink(bugReportDetails) {
return (
"https://github.com/metabase/metabase/issues/new?title=&labels=Type:Bug&body=" +
encodeURIComponent(template + "\n```json\n" + bugReportDetails + "\n```")
);
}
function discourseLink(bugReportDetails) {
return (
"http://discourse.metabase.com/new-topic?category_id=7&body=" +
encodeURIComponent("```json\n" + bugReportDetails + "\n```")
);
}
const HelpLink = ({ title, description, link }) => (
<li className="mb2">
<ExternalLink
className="bordered border-brand-hover rounded transition-border flex p2 no-decoration"
href={link}
>
<div>
<h3 className="text-brand">{title}</h3>
<p className="m0 mt1">{description}</p>
</div>
</ExternalLink>
</li>
);
const InfoBlock = ({ children }) => (
<Box p={2} className="bordered rounded bg-light relative">
<Box m={2} className="absolute top right text-brand-hover cursor-pointer">
<CopyButton value={children} />
</Box>
<Code>{children}</Code>
</Box>
);
export default class Help extends Component {
state = {
details: { "browser-info": navigatorInfo() },
};
async fetchDetails() {
const details = await UtilApi.bug_report_details();
this.setState({ details: { ...this.state.details, ...details } });
}
componentWillMount() {
this.fetchDetails();
}
render() {
const { details } = this.state;
const detailString = JSON.stringify(details, null, 2);
return (
<Box p={3}>
<AdminHeader title={t`Help`} className="mb2" />
<Box my={2} style={{ maxWidth: "468px" }}>
<ol>
<HelpLink
title="Metabase Documentation"
description="Includes a troubleshooting guide"
link={MetabaseSettings.docsUrl()}
/>
<HelpLink
title="Post on the Metabase support forum"
description="A community forum for all things Metabase"
link={discourseLink(detailString)}
/>
<HelpLink
title="File a bug report"
description="Create a GitHub issue (includes the diagnostic info below)"
link={githubIssueLink(detailString)}
/>
</ol>
</Box>
<Box my={2}>
<AdminHeader title={t`Diagnostic Info`} className="mb2" />
<p>Please include these details in support requests. Thank you!</p>
<InfoBlock>{detailString}</InfoBlock>
</Box>
</Box>
);
}
}
......@@ -18,6 +18,10 @@ export default class TroubleshootingApp extends Component {
<AdminLayout
sidebar={
<LeftNavPane>
<LeftNavPaneItem
name={t`Help`}
path="/admin/troubleshooting/help"
/>
<LeftNavPaneItem
name={t`Tasks`}
path="/admin/troubleshooting/tasks"
......
......@@ -309,6 +309,7 @@ export const UtilApi = {
password_check: POST("/api/util/password_check"),
random_token: GET("/api/util/random_token"),
logs: GET("/api/util/logs"),
bug_report_details: GET("/api/util/bug_report_details"),
};
export const GeoJSONApi = {
......
......@@ -3,8 +3,10 @@
page tasks."
(:require [compojure.core :refer [GET POST]]
[crypto.random :as crypto-random]
[metabase
[logger :as logger]
[troubleshooting :as troubleshooting]]
[metabase.api.common :as api]
[metabase.logger :as logger]
[metabase.util
[schema :as su]
[stats :as stats]]))
......@@ -34,5 +36,10 @@
[]
{:token (crypto-random/hex 32)})
(api/defendpoint GET "/bug_report_details"
[]
(api/check-superuser)
{:system-info (troubleshooting/system-info)
:metabase-info (troubleshooting/metabase-info)})
(api/define-routes)
......@@ -13,6 +13,7 @@
[server :as server]
[setup :as setup]
[task :as task]
[troubleshooting :as troubleshooting]
[util :as u]]
[metabase.core.initialization-status :as init-status]
[metabase.driver.util :as driver.u]
......@@ -56,7 +57,7 @@
"General application initialization function which should be run once at application startup."
[]
(log/info (trs "Starting Metabase version {0} ..." config/mb-version-string))
(log/info (trs "System timezone is ''{0}'' ..." (System/getProperty "user.timezone")))
(log/info (trs "System info:\n {0}" (u/pprint-to-str (troubleshooting/system-info))))
(init-status/set-progress! 0.1)
;; First of all, lets register a shutdown hook that will tidy things up for us on app exit
......
(ns metabase.troubleshooting
(:require [metabase
[config :as mc]
[db :as mdb]]
[metabase.models.setting :as setting]
[metabase.util.stats :as mus]
[toucan.db :as tdb]))
(defn system-info
"System info we ask for for bug reports"
[]
(into (sorted-map)
(select-keys (System/getProperties) ["java.runtime.name"
"java.runtime.version"
"java.vendor"
"java.vendor.url"
"java.version"
"java.vm.name"
"java.vm.version"
"os.name"
"os.version"
"user.language"
"user.timezone"])))
(defn metabase-info
"Make it easy for the user to tell us what they're using"
[]
{:databases (->> (tdb/select 'Database) (map :engine) distinct)
:hosting-env (mus/environment-type)
:application-database (mdb/db-type)
:run-mode (mc/config-kw :mb-run-mode)
:version mc/mb-version-info
:settings {:report-timezone (setting/get :report-timezone)}})
......@@ -127,7 +127,7 @@
[]
(:min (db/select-one [User [:%min.date_joined :min]])))
(defn- environment-type
(defn environment-type
"Figure out what we're running under"
[]
(cond
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment