Merge pull request #3896 from influxdata/logs-viewer/connect-logs-viewer-to-api
Connect Logs Viewer page to APIpull/10616/head
commit
650f011863
|
@ -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
|
||||
|
||||
|
|
|
@ -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"}}`,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -14,7 +14,11 @@ 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
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -41,6 +41,7 @@ type getRoutesResponse struct {
|
|||
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
|
||||
|
@ -89,7 +90,10 @@ func (a *AllRoutes) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
Config: getConfigLinksResponse{
|
||||
Self: "/chronograf/v1/config",
|
||||
Auth: "/chronograf/v1/config/auth",
|
||||
LogViewer: "/chronograf/v1/config/logviewer",
|
||||
},
|
||||
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{
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
]
|
||||
|
||||
|
|
Loading…
Reference in New Issue