Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ NOTE: As semantic versioning states all 0.y.z releases can contain breaking chan
### Added

- [#177](https://github.com/kobsio/kobs/pull/177): [istio] Add Istio plugin to get an overview of all applications in the service mesh.
- [#182](https://github.com/kobsio/kobs/pull/182): [istio] Add top and tap commands and add details view for metrics.

### Fixed

Expand Down
4 changes: 2 additions & 2 deletions cmd/kobs/plugins/plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ func Register(clusters *clusters.Clusters, config Config) chi.Router {
dashboardsRouter := dashboards.Register(clusters, router.plugins, config.Dashboards)
prometheusRouter, prometheusInstances := prometheus.Register(clusters, router.plugins, config.Prometheus)
elasticsearchRouter := elasticsearch.Register(clusters, router.plugins, config.Elasticsearch)
clickhouseRouter := clickhouse.Register(clusters, router.plugins, config.Clickhouse)
clickhouseRouter, clickhouseInstances := clickhouse.Register(clusters, router.plugins, config.Clickhouse)
jaegerRouter := jaeger.Register(clusters, router.plugins, config.Jaeger)
kialiRouter := kiali.Register(clusters, router.plugins, config.Kiali)
istioRouter := istio.Register(clusters, router.plugins, config.Istio, prometheusInstances)
istioRouter := istio.Register(clusters, router.plugins, config.Istio, prometheusInstances, clickhouseInstances)
fluxRouter := flux.Register(clusters, router.plugins, config.Flux)
opsgenieRouter := opsgenie.Register(clusters, router.plugins, config.Opsgenie)
sqlRouter := sql.Register(clusters, router.plugins, config.SQL)
Expand Down
2 changes: 1 addition & 1 deletion docs/resources/resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ If you want to view the Yaml representation of the resource you can select the c

![YAML](assets/resources-yaml.png)

Next to the yaml representation, you find a seconde tab events, which shows all events, which are related to the selected object. The events are retrieved with a field selector and the name of the resource: `fieldSelector=involvedObject.name=<NAME-OF-THE-RESOURCE>`.
Next to the yaml representation, you find a second tab events, which shows all events, which are related to the selected object. The events are retrieved with a field selector and the name of the resource: `fieldSelector=involvedObject.name=<NAME-OF-THE-RESOURCE>`.

![Events](assets/resources-events.png)

Expand Down
2 changes: 1 addition & 1 deletion plugins/applications/src/components/page/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { IPluginPageProps } from '@kobsio/plugin-core';

// The page for the applications plugin, supports two different routes: One for showing a gallery / topology of
// applications, where the user can select a list of clusters and namespaces for which he wants to get the applications
// and a seconde one for showing a single application.
// and a second one for showing a single application.
const Page: React.FunctionComponent<IPluginPageProps> = ({ name, displayName, description }: IPluginPageProps) => {
return (
<Switch>
Expand Down
6 changes: 3 additions & 3 deletions plugins/clickhouse/clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (router *Router) getLogs(w http.ResponseWriter, r *http.Request) {
done <- true
}()

documents, fields, count, took, buckets, err := i.GetLogs(r.Context(), query, order, orderBy, parsedTimeStart, parsedTimeEnd)
documents, fields, count, took, buckets, err := i.GetLogs(r.Context(), query, order, orderBy, 1000, parsedTimeStart, parsedTimeEnd)
if err != nil {
errresponse.Render(w, r, err, http.StatusBadRequest, "Could not get logs")
return
Expand Down Expand Up @@ -207,7 +207,7 @@ func (router *Router) getAggregation(w http.ResponseWriter, r *http.Request) {
}

// Register returns a new router which can be used in the router for the kobs rest api.
func Register(clusters *clusters.Clusters, plugins *plugin.Plugins, config Config) chi.Router {
func Register(clusters *clusters.Clusters, plugins *plugin.Plugins, config Config) (chi.Router, []*instance.Instance) {
var instances []*instance.Instance

for _, cfg := range config {
Expand Down Expand Up @@ -235,5 +235,5 @@ func Register(clusters *clusters.Clusters, plugins *plugin.Plugins, config Confi
router.Get("/logs/{name}", router.getLogs)
router.Get("/aggregation/{name}", router.getAggregation)

return router
return router, instances
}
45 changes: 42 additions & 3 deletions plugins/clickhouse/pkg/instance/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type Instance struct {

// GetLogs parses the given query into the sql syntax, which is then run against the ClickHouse instance. The returned
// rows are converted into a document schema which can be used by our UI.
func (i *Instance) GetLogs(ctx context.Context, query, order, orderBy string, timeStart, timeEnd int64) ([]map[string]interface{}, []string, int64, int64, []Bucket, error) {
func (i *Instance) GetLogs(ctx context.Context, query, order, orderBy string, limit, timeStart, timeEnd int64) ([]map[string]interface{}, []string, int64, int64, []Bucket, error) {
var count int64
var buckets []Bucket
var documents []map[string]interface{}
Expand Down Expand Up @@ -120,7 +120,7 @@ func (i *Instance) GetLogs(ctx context.Context, query, order, orderBy string, ti
// start date. In these follow up calls the start time isn't changed again, because we are skipping the count
// and bucket queries.
for i := len(buckets) - 1; i >= 0; i-- {
if count < 1000 && buckets[i].Count > 0 {
if count < limit && buckets[i].Count > 0 {
if timeConditions == "" {
timeConditions = fmt.Sprintf("(timestamp >= FROM_UNIXTIME(%d) AND timestamp <= FROM_UNIXTIME(%d))", buckets[i].Interval, buckets[i].Interval+interval)
} else {
Expand All @@ -144,7 +144,7 @@ func (i *Instance) GetLogs(ctx context.Context, query, order, orderBy string, ti
// Now we are building and executing our sql query. We always return all fields from the logs table, where the
// timestamp of a row is within the selected query range and the parsed query. We also order all the results by the
// timestamp field and limiting the results / using a offset for pagination.
sqlQueryRawLogs := fmt.Sprintf("SELECT %s FROM %s.logs WHERE (%s) %s ORDER BY %s LIMIT 1000 SETTINGS skip_unavailable_shards = 1", defaultColumns, i.database, timeConditions, conditions, parsedOrder)
sqlQueryRawLogs := fmt.Sprintf("SELECT %s FROM %s.logs WHERE (%s) %s ORDER BY %s LIMIT %d SETTINGS skip_unavailable_shards = 1", defaultColumns, i.database, timeConditions, conditions, parsedOrder, limit)
log.WithFields(logrus.Fields{"query": sqlQueryRawLogs}).Tracef("sql query raw logs")
rowsRawLogs, err := i.client.QueryContext(ctx, sqlQueryRawLogs)
if err != nil {
Expand Down Expand Up @@ -245,6 +245,45 @@ func (i *Instance) GetAggregation(ctx context.Context, limit int64, groupBy, ope
return data, nil
}

// GetRawQueryResults returns all rows for the user provided SQL query. This function should only be used by other
// plugins. If users should be able to directly access a Clickhouse instance you can expose the instance using the SQL
// plugin.
func (i *Instance) GetRawQueryResults(ctx context.Context, query string) ([][]interface{}, []string, error) {
log.WithFields(logrus.Fields{"query": query}).Tracef("raw sql query")

rows, err := i.client.QueryContext(ctx, query)
if err != nil {
return nil, nil, err
}
defer rows.Close()

var columns []string
columns, err = rows.Columns()
if err != nil {
return nil, nil, err
}
columnsLen := len(columns)

var result [][]interface{}

for rows.Next() {
var r []interface{}
r = make([]interface{}, columnsLen)

for i := 0; i < columnsLen; i++ {
r[i] = new(interface{})
}

if err := rows.Scan(r...); err != nil {
return nil, nil, err
}

result = append(result, r)
}

return result, columns, nil
}

// New returns a new ClickHouse instance for the given configuration.
func New(config Config) (*Instance, error) {
if config.WriteTimeout == "" {
Expand Down
10 changes: 5 additions & 5 deletions plugins/clickhouse/pkg/instance/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,16 @@ func splitOperator(condition string, materializedColumns []string) (string, erro
return handleConditionParts(notIlike[0], notIlike[1], "!~", materializedColumns)
}

equal := strings.Split(condition, "=")
if len(equal) == 2 {
return handleConditionParts(equal[0], equal[1], "=", materializedColumns)
}

regex := strings.Split(condition, "~")
if len(regex) == 2 {
return handleConditionParts(regex[0], regex[1], "~", materializedColumns)
}

equal := strings.Split(condition, "=")
if len(equal) == 2 {
return handleConditionParts(equal[0], equal[1], "=", materializedColumns)
}

if strings.Contains(condition, "_exists_ ") {
return handleExistsCondition(strings.TrimLeft(strings.TrimSpace(condition), "_exists_ "), materializedColumns), nil
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/flux/src/components/page/PageList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const PageList: React.FunctionComponent<IPageListProps> = ({
},
);

// refetchhWithDelay is used to call the refetch function to get the resource, but with a delay of 3 seconde. This is
// refetchhWithDelay is used to call the refetch function to get the resource, but with a delay of 3 seconds. This is
// required, because sometime the Kubenretes isn't that fast after an action (edit, delete, ...) was triggered.
const refetchhWithDelay = (): void => {
setTimeout(() => {
Expand Down
2 changes: 1 addition & 1 deletion plugins/flux/src/components/panel/PanelList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const PanelList: React.FunctionComponent<IPanelListProps> = ({
},
);

// refetchhWithDelay is used to call the refetch function to get the resource, but with a delay of 3 seconde. This is
// refetchhWithDelay is used to call the refetch function to get the resource, but with a delay of 3 seconds. This is
// required, because sometime the Kubenretes isn't that fast after an action (edit, delete, ...) was triggered.
const refetchhWithDelay = (): void => {
setTimeout(() => {
Expand Down
Loading