Merge pull request #3896 from influxdata/logs-viewer/connect-logs-viewer-to-api

Connect Logs Viewer page to API
pull/10616/head
Alirie Gray 2018-07-12 11:51:25 -07:00 committed by GitHub
commit 650f011863
10 changed files with 83 additions and 147 deletions

View File

@ -7,6 +7,7 @@
1. [#3556](https://github.com/influxdata/chronograf/pull/3556): Add ability to override template variables and time ranges via URL query
1. [#3814](https://github.com/influxdata/chronograf/pull/3814): Add pprof routes to chronograf server
1. [#3806](https://github.com/influxdata/chronograf/pull/3806): Add API to get/update Log Viewer UI config
1. [#3896](https://github.com/influxdata/chronograf/pull/3896): Consume new Log Viewer config API in client to allow user to configure log viewer UI for their organization
### UI Improvements

View File

@ -3403,42 +3403,7 @@ func TestServer(t *testing.T) {
},
wants: wants{
statusCode: 200,
body: `
{
"layouts": "/chronograf/v1/layouts",
"users": "/chronograf/v1/organizations/default/users",
"allUsers": "/chronograf/v1/users",
"organizations": "/chronograf/v1/organizations",
"mappings": "/chronograf/v1/mappings",
"sources": "/chronograf/v1/sources",
"me": "/chronograf/v1/me",
"environment": "/chronograf/v1/env",
"dashboards": "/chronograf/v1/dashboards",
"config": {
"self": "/chronograf/v1/config",
"auth": "/chronograf/v1/config/auth",
"logViewer": "/chronograf/v1/config/logviewer"
},
"auth": [
{
"name": "github",
"label": "Github",
"login": "/oauth/github/login",
"logout": "/oauth/github/logout",
"callback": "/oauth/github/callback"
}
],
"logout": "/oauth/logout",
"external": {
"statusFeed": ""
},
"flux": {
"ast": "/chronograf/v1/flux/ast",
"self": "/chronograf/v1/flux",
"suggestions": "/chronograf/v1/flux/suggestions"
}
}
`,
body: `{"layouts":"/chronograf/v1/layouts","users":"/chronograf/v1/organizations/default/users","allUsers":"/chronograf/v1/users","organizations":"/chronograf/v1/organizations","mappings":"/chronograf/v1/mappings","sources":"/chronograf/v1/sources","me":"/chronograf/v1/me","environment":"/chronograf/v1/env","dashboards":"/chronograf/v1/dashboards","config":{"self":"/chronograf/v1/config","auth":"/chronograf/v1/config/auth"},"orgConfig":{"self":"/chronograf/v1/org_config","logViewer":"/chronograf/v1/org_config/logviewer"},"auth":[{"name":"github","label":"Github","login":"/oauth/github/login","logout":"/oauth/github/logout","callback":"/oauth/github/callback"}],"logout":"/oauth/logout","external":{"statusFeed":""},"flux":{"ast":"/chronograf/v1/flux/ast","self":"/chronograf/v1/flux","suggestions":"/chronograf/v1/flux/suggestions"}}`,
},
},
{
@ -3492,42 +3457,7 @@ func TestServer(t *testing.T) {
},
wants: wants{
statusCode: 200,
body: `
{
"layouts": "/chronograf/v1/layouts",
"users": "/chronograf/v1/organizations/1/users",
"allUsers": "/chronograf/v1/users",
"organizations": "/chronograf/v1/organizations",
"mappings": "/chronograf/v1/mappings",
"sources": "/chronograf/v1/sources",
"me": "/chronograf/v1/me",
"environment": "/chronograf/v1/env",
"dashboards": "/chronograf/v1/dashboards",
"config": {
"self": "/chronograf/v1/config",
"auth": "/chronograf/v1/config/auth",
"logViewer": "/chronograf/v1/config/logviewer"
},
"auth": [
{
"name": "github",
"label": "Github",
"login": "/oauth/github/login",
"logout": "/oauth/github/logout",
"callback": "/oauth/github/callback"
}
],
"logout": "/oauth/logout",
"external": {
"statusFeed": ""
},
"flux": {
"ast": "/chronograf/v1/flux/ast",
"self": "/chronograf/v1/flux",
"suggestions": "/chronograf/v1/flux/suggestions"
}
}
`,
body: `{"layouts":"/chronograf/v1/layouts","users":"/chronograf/v1/organizations/1/users","allUsers":"/chronograf/v1/users","organizations":"/chronograf/v1/organizations","mappings":"/chronograf/v1/mappings","sources":"/chronograf/v1/sources","me":"/chronograf/v1/me","environment":"/chronograf/v1/env","dashboards":"/chronograf/v1/dashboards","config":{"self":"/chronograf/v1/config","auth":"/chronograf/v1/config/auth"},"orgConfig":{"self":"/chronograf/v1/org_config","logViewer":"/chronograf/v1/org_config/logviewer"},"auth":[{"name":"github","label":"Github","login":"/oauth/github/login","logout":"/oauth/github/logout","callback":"/oauth/github/callback"}],"logout":"/oauth/logout","external":{"statusFeed":""},"flux":{"ast":"/chronograf/v1/flux/ast","self":"/chronograf/v1/flux","suggestions":"/chronograf/v1/flux/suggestions"}}`,
},
},
}

View File

@ -12,9 +12,13 @@ type getFluxLinksResponse struct {
}
type getConfigLinksResponse struct {
Self string `json:"self"` // Location of the whole global application configuration
Auth string `json:"auth"` // Location of the auth section of the global application configuration
LogViewer string `json:"logViewer"` // Location of the log viewer section of the global application configuration
Self string `json:"self"` // Location of the whole global application configuration
Auth string `json:"auth"` // Location of the auth section of the global application configuration
}
type getOrganizationConfigLinksResponse struct {
Self string `json:"self"` // Location of the organization configuration
LogViewer string `json:"logViewer"` // Location of the organization-specific log viewer configuration
}
type getExternalLinksResponse struct {

View File

@ -31,20 +31,21 @@ func (r *AuthRoutes) Lookup(provider string) (AuthRoute, bool) {
}
type getRoutesResponse struct {
Layouts string `json:"layouts"` // Location of the layouts endpoint
Users string `json:"users"` // Location of the users endpoint
AllUsers string `json:"allUsers"` // Location of the raw users endpoint
Organizations string `json:"organizations"` // Location of the organizations endpoint
Mappings string `json:"mappings"` // Location of the application mappings endpoint
Sources string `json:"sources"` // Location of the sources endpoint
Me string `json:"me"` // Location of the me endpoint
Environment string `json:"environment"` // Location of the environement endpoint
Dashboards string `json:"dashboards"` // Location of the dashboards endpoint
Config getConfigLinksResponse `json:"config"` // Location of the config endpoint and its various sections
Auth []AuthRoute `json:"auth"` // Location of all auth routes.
Logout *string `json:"logout,omitempty"` // Location of the logout route for all auth routes
ExternalLinks getExternalLinksResponse `json:"external"` // All external links for the client to use
Flux getFluxLinksResponse `json:"flux"`
Layouts string `json:"layouts"` // Location of the layouts endpoint
Users string `json:"users"` // Location of the users endpoint
AllUsers string `json:"allUsers"` // Location of the raw users endpoint
Organizations string `json:"organizations"` // Location of the organizations endpoint
Mappings string `json:"mappings"` // Location of the application mappings endpoint
Sources string `json:"sources"` // Location of the sources endpoint
Me string `json:"me"` // Location of the me endpoint
Environment string `json:"environment"` // Location of the environement endpoint
Dashboards string `json:"dashboards"` // Location of the dashboards endpoint
Config getConfigLinksResponse `json:"config"` // Location of the config endpoint and its various sections
OrganizationConfig getOrganizationConfigLinksResponse `json:"orgConfig"` // Location of the organization config endpoint
Auth []AuthRoute `json:"auth"` // Location of all auth routes.
Logout *string `json:"logout,omitempty"` // Location of the logout route for all auth routes
ExternalLinks getExternalLinksResponse `json:"external"` // All external links for the client to use
Flux getFluxLinksResponse `json:"flux"`
}
// AllRoutes is a handler that returns all links to resources in Chronograf server, as well as
@ -87,9 +88,12 @@ func (a *AllRoutes) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Mappings: "/chronograf/v1/mappings",
Dashboards: "/chronograf/v1/dashboards",
Config: getConfigLinksResponse{
Self: "/chronograf/v1/config",
Auth: "/chronograf/v1/config/auth",
LogViewer: "/chronograf/v1/config/logviewer",
Self: "/chronograf/v1/config",
Auth: "/chronograf/v1/config/auth",
},
OrganizationConfig: getOrganizationConfigLinksResponse{
Self: "/chronograf/v1/org_config",
LogViewer: "/chronograf/v1/org_config/logviewer",
},
Auth: make([]AuthRoute, len(a.AuthRoutes)), // We want to return at least an empty array, rather than null
ExternalLinks: getExternalLinksResponse{

View File

@ -29,7 +29,7 @@ func TestAllRoutes(t *testing.T) {
if err := json.Unmarshal(body, &routes); err != nil {
t.Error("TestAllRoutes not able to unmarshal JSON response")
}
want := `{"layouts":"/chronograf/v1/layouts","users":"/chronograf/v1/organizations/default/users","allUsers":"/chronograf/v1/users","organizations":"/chronograf/v1/organizations","mappings":"/chronograf/v1/mappings","sources":"/chronograf/v1/sources","me":"/chronograf/v1/me","environment":"/chronograf/v1/env","dashboards":"/chronograf/v1/dashboards","config":{"self":"/chronograf/v1/config","auth":"/chronograf/v1/config/auth","logViewer":"/chronograf/v1/config/logviewer"},"auth":[],"external":{"statusFeed":""},"flux":{"ast":"/chronograf/v1/flux/ast","self":"/chronograf/v1/flux","suggestions":"/chronograf/v1/flux/suggestions"}}
want := `{"layouts":"/chronograf/v1/layouts","users":"/chronograf/v1/organizations/default/users","allUsers":"/chronograf/v1/users","organizations":"/chronograf/v1/organizations","mappings":"/chronograf/v1/mappings","sources":"/chronograf/v1/sources","me":"/chronograf/v1/me","environment":"/chronograf/v1/env","dashboards":"/chronograf/v1/dashboards","config":{"self":"/chronograf/v1/config","auth":"/chronograf/v1/config/auth"},"orgConfig":{"self":"/chronograf/v1/org_config","logViewer":"/chronograf/v1/org_config/logviewer"},"auth":[],"external":{"statusFeed":""},"flux":{"ast":"/chronograf/v1/flux/ast","self":"/chronograf/v1/flux","suggestions":"/chronograf/v1/flux/suggestions"}}
`
if want != string(body) {
t.Errorf("TestAllRoutes\nwanted\n*%s*\ngot\n*%s*", want, string(body))
@ -67,7 +67,7 @@ func TestAllRoutesWithAuth(t *testing.T) {
if err := json.Unmarshal(body, &routes); err != nil {
t.Error("TestAllRoutesWithAuth not able to unmarshal JSON response")
}
want := `{"layouts":"/chronograf/v1/layouts","users":"/chronograf/v1/organizations/default/users","allUsers":"/chronograf/v1/users","organizations":"/chronograf/v1/organizations","mappings":"/chronograf/v1/mappings","sources":"/chronograf/v1/sources","me":"/chronograf/v1/me","environment":"/chronograf/v1/env","dashboards":"/chronograf/v1/dashboards","config":{"self":"/chronograf/v1/config","auth":"/chronograf/v1/config/auth","logViewer":"/chronograf/v1/config/logviewer"},"auth":[{"name":"github","label":"GitHub","login":"/oauth/github/login","logout":"/oauth/github/logout","callback":"/oauth/github/callback"}],"logout":"/oauth/logout","external":{"statusFeed":""},"flux":{"ast":"/chronograf/v1/flux/ast","self":"/chronograf/v1/flux","suggestions":"/chronograf/v1/flux/suggestions"}}
want := `{"layouts":"/chronograf/v1/layouts","users":"/chronograf/v1/organizations/default/users","allUsers":"/chronograf/v1/users","organizations":"/chronograf/v1/organizations","mappings":"/chronograf/v1/mappings","sources":"/chronograf/v1/sources","me":"/chronograf/v1/me","environment":"/chronograf/v1/env","dashboards":"/chronograf/v1/dashboards","config":{"self":"/chronograf/v1/config","auth":"/chronograf/v1/config/auth"},"orgConfig":{"self":"/chronograf/v1/org_config","logViewer":"/chronograf/v1/org_config/logviewer"},"auth":[{"name":"github","label":"GitHub","login":"/oauth/github/login","logout":"/oauth/github/logout","callback":"/oauth/github/callback"}],"logout":"/oauth/logout","external":{"statusFeed":""},"flux":{"ast":"/chronograf/v1/flux/ast","self":"/chronograf/v1/flux","suggestions":"/chronograf/v1/flux/suggestions"}}
`
if want != string(body) {
t.Errorf("TestAllRoutesWithAuth\nwanted\n*%s*\ngot\n*%s*", want, string(body))
@ -100,7 +100,7 @@ func TestAllRoutesWithExternalLinks(t *testing.T) {
if err := json.Unmarshal(body, &routes); err != nil {
t.Error("TestAllRoutesWithExternalLinks not able to unmarshal JSON response")
}
want := `{"layouts":"/chronograf/v1/layouts","users":"/chronograf/v1/organizations/default/users","allUsers":"/chronograf/v1/users","organizations":"/chronograf/v1/organizations","mappings":"/chronograf/v1/mappings","sources":"/chronograf/v1/sources","me":"/chronograf/v1/me","environment":"/chronograf/v1/env","dashboards":"/chronograf/v1/dashboards","config":{"self":"/chronograf/v1/config","auth":"/chronograf/v1/config/auth","logViewer":"/chronograf/v1/config/logviewer"},"auth":[],"external":{"statusFeed":"http://pineapple.life/feed.json","custom":[{"name":"cubeapple","url":"https://cube.apple"}]},"flux":{"ast":"/chronograf/v1/flux/ast","self":"/chronograf/v1/flux","suggestions":"/chronograf/v1/flux/suggestions"}}
want := `{"layouts":"/chronograf/v1/layouts","users":"/chronograf/v1/organizations/default/users","allUsers":"/chronograf/v1/users","organizations":"/chronograf/v1/organizations","mappings":"/chronograf/v1/mappings","sources":"/chronograf/v1/sources","me":"/chronograf/v1/me","environment":"/chronograf/v1/env","dashboards":"/chronograf/v1/dashboards","config":{"self":"/chronograf/v1/config","auth":"/chronograf/v1/config/auth"},"orgConfig":{"self":"/chronograf/v1/org_config","logViewer":"/chronograf/v1/org_config/logviewer"},"auth":[],"external":{"statusFeed":"http://pineapple.life/feed.json","custom":[{"name":"cubeapple","url":"https://cube.apple"}]},"flux":{"ast":"/chronograf/v1/flux/ast","self":"/chronograf/v1/flux","suggestions":"/chronograf/v1/flux/suggestions"}}
`
if want != string(body) {
t.Errorf("TestAllRoutesWithExternalLinks\nwanted\n*%s*\ngot\n*%s*", want, string(body))

View File

@ -13,17 +13,13 @@ import {
buildBackwardLogQuery,
parseHistogramQueryResponse,
} from 'src/logs/utils'
import {
logConfigServerToUI,
// logConfigUIToServer
} from 'src/logs/utils/config'
import {logConfigServerToUI, logConfigUIToServer} from 'src/logs/utils/config'
import {getDeep} from 'src/utils/wrappers'
import {
executeQueryAsync,
// getLogConfig as getLogConfigAJAX,
// updateLogConfig as updateLogConfigAJAX,
getLogConfig as getLogConfigAJAX,
updateLogConfig as updateLogConfigAJAX,
} from 'src/logs/api'
import {serverLogData} from 'src/logs/data/serverLogData'
import {LogsState, Filter, TableData, LogConfig} from 'src/types/logs'
export const INITIAL_LIMIT = 100
@ -713,10 +709,8 @@ export const changeZoomAsync = (timeRange: TimeRange) => async (
export const getLogConfigAsync = (url: string) => async (
dispatch: Dispatch<SetConfigsAction>
): Promise<void> => {
url = url
try {
// const {data} = await getLogConfigAJAX(url)
const data = serverLogData
const {data} = await getLogConfigAJAX(url)
const logConfig = logConfigServerToUI(data)
dispatch(setConfig(logConfig))
} catch (error) {
@ -727,10 +721,9 @@ export const getLogConfigAsync = (url: string) => async (
export const updateLogConfigAsync = (url: string, config: LogConfig) => async (
dispatch: Dispatch<SetConfigsAction>
): Promise<void> => {
url = url
try {
// const configForServer = logConfigUIToServer(config)
// await updateLogConfigAJAX(url, configForServer)
const configForServer = logConfigUIToServer(config)
await updateLogConfigAJAX(url, configForServer)
dispatch(setConfig(config))
} catch (error) {
console.error(error)

View File

@ -438,19 +438,21 @@ class LogsPage extends Component<Props, State> {
)
}
private handleUpdateSeverityLevels = (
private handleUpdateSeverityLevels = async (
severityLevelColors: SeverityLevelColor[]
): void => {
): Promise<void> => {
const {logConfig} = this.props
this.props.updateConfig(this.logConfigLink, {
await this.props.updateConfig(this.logConfigLink, {
...logConfig,
severityLevelColors,
})
}
private handleUpdateSeverityFormat = (format: SeverityFormat): void => {
private handleUpdateSeverityFormat = async (
format: SeverityFormat
): Promise<void> => {
const {logConfig} = this.props
this.props.updateConfig(this.logConfigLink, {
await this.props.updateConfig(this.logConfigLink, {
...logConfig,
severityFormat: format,
})
@ -466,9 +468,11 @@ class LogsPage extends Component<Props, State> {
return severityFormat
}
private handleUpdateColumns = (tableColumns: LogsTableColumn[]): void => {
private handleUpdateColumns = async (
tableColumns: LogsTableColumn[]
): Promise<void> => {
const {logConfig} = this.props
this.props.updateConfig(this.logConfigLink, {
await this.props.updateConfig(this.logConfigLink, {
...logConfig,
tableColumns,
})
@ -478,7 +482,7 @@ class LogsPage extends Component<Props, State> {
const mapStateToProps = ({
sources,
links: {
config: {logViewer},
orgConfig: {logViewer},
},
logs: {
newRowsAdded,

View File

@ -99,8 +99,8 @@ export const getLevelColorsFromColumn = (
): SeverityLevelColor[] => {
const colors = column.encodings.filter(e => e.type === EncodingTypes.color)
return colors.map(c => {
const level: SeverityLevelOptions = SeverityLevelOptions[c.value]
const color: SeverityColorOptions = SeverityColorOptions[c.name]
const level: SeverityLevelOptions = SeverityLevelOptions[c.name]
const color: SeverityColorOptions = SeverityColorOptions[c.value]
return {level, color}
})
}
@ -171,7 +171,7 @@ export const getColorEncodings = (
levelColors: SeverityLevelColor[]
): ServerEncoding[] => {
return levelColors.map(({color, level}) => {
return {type: EncodingTypes.color, name: color, value: level}
return {type: EncodingTypes.color, value: color, name: level}
})
}

View File

@ -404,13 +404,13 @@ export const serverLogColumns: ServerColumn[] = [
},
{
type: 'color',
value: 'alert',
name: 'pearl',
name: 'alert',
value: 'pearl',
},
{
type: 'color',
value: 'warning',
name: 'wolf',
name: 'warning',
value: 'wolf',
},
],
},

View File

@ -48,13 +48,13 @@ const sortedServerColumns = () => {
},
{
type: 'color',
value: 'alert',
name: 'pearl',
name: 'alert',
value: 'pearl',
},
{
type: 'color',
value: 'warning',
name: 'wolf',
name: 'warning',
value: 'wolf',
},
],
},
@ -233,13 +233,13 @@ describe('Logs.Config', () => {
},
{
type: 'color',
name: 'pineapple',
value: 'emerg',
name: 'emerg',
value: 'pineapple',
},
{
type: 'color',
name: 'fire',
value: 'err',
name: 'err',
value: 'fire',
},
],
}
@ -365,23 +365,23 @@ describe('Logs.Config', () => {
const expectedEncodings = [
{
type: 'color',
value: 'emerg',
name: SeverityColorOptions.pearl,
name: 'emerg',
value: SeverityColorOptions.pearl,
},
{
type: 'color',
value: 'alert',
name: SeverityColorOptions.mist,
name: 'alert',
value: SeverityColorOptions.mist,
},
{
type: 'color',
value: 'crit',
name: SeverityColorOptions.wolf,
name: 'crit',
value: SeverityColorOptions.wolf,
},
{
type: 'color',
value: 'err',
name: SeverityColorOptions.graphite,
name: 'err',
value: SeverityColorOptions.graphite,
},
]
@ -436,23 +436,23 @@ describe('Logs.Config', () => {
},
{
type: 'color',
value: 'emerg',
name: SeverityColorOptions.pearl,
name: 'emerg',
value: SeverityColorOptions.pearl,
},
{
type: 'color',
value: 'alert',
name: SeverityColorOptions.mist,
name: 'alert',
value: SeverityColorOptions.mist,
},
{
type: 'color',
value: 'crit',
name: SeverityColorOptions.wolf,
name: 'crit',
value: SeverityColorOptions.wolf,
},
{
type: 'color',
value: 'err',
name: SeverityColorOptions.graphite,
name: 'err',
value: SeverityColorOptions.graphite,
},
]