Skip to content

Commit

Permalink
Add roles and run report command (#237)
Browse files Browse the repository at this point in the history
* Add roles and run report command
* minor updates
  • Loading branch information
tmiddlet2666 authored Oct 15, 2024
1 parent e13cdd1 commit 4fe680c
Show file tree
Hide file tree
Showing 13 changed files with 157 additions and 12 deletions.
28 changes: 27 additions & 1 deletion docs/reference/66_reporters.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2021, 2023 Oracle and/or its affiliates.
Copyright (c) 2021, 2024 Oracle and/or its affiliates.
Licensed under the Universal Permissive License v 1.0 as shown at
https://oss.oracle.com/licenses/upl.

Expand All @@ -18,6 +18,7 @@ There are various commands that allow you to work with and manage Reporters.
* <<start-reporter, `cohctl start reporter`>> - starts a reporter on a specific node
* <<stop-reporter, `cohctl stop reporter`>> - stops a reporter on a specific node
* <<set-reporter, `cohctl set reporter`>> - sets a reporter attribute for one or more members
* <<run-report, `cohctl run report`>> - runs a report on a specific node and returns the report output in JSON
[#get-reporters]
==== Get Reporters
Expand Down Expand Up @@ -168,9 +169,34 @@ NODE ID STATE CONFIG FILE OUTPUT PATH BATCH# LAST REPORT LA
2 Stopped reports/report-group.xml /tmp 0 0ms 0.0000ms 60 false
----
[#run-report]
==== Run
include::../../build/_output/docs-gen/run_report.adoc[tag=text]
NOTE: The otuput will always be JSON. You can use `-o jsonpath=...` to use jsonpath expression or pipe through to a utility such as `jq`.
This REST endpoint that this command uses is only available in the most recent Coherence releases.
You will receive a HTTP 400 error if it is not supported in your Coherence version.
[source,bash]
----
cohctl run report report-node -c local -n 1
----
Output:
[source,bash]
----
{"items":[{"RefreshTime":"Tue Oct 15 09:07:55 AWST 2024","ReportTime":"Tue Oct 15 09:07:55 AWST 2024",
...
"RoleName":"CoherenceServer","Addres,"BatchCounter":"0","rowID":3}]}
----
NOTE: The output above is truncated for readability.
=== See Also
* <<docs/reference/20_services.adoc,Services>>
* <<docs/examples/10_jsonpath.adoc,Using JSONPath>>
10 changes: 6 additions & 4 deletions pkg/cmd/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ const (
back = "back"
all = "all"
partitionDisplayType = "partition"
access = "access"
storage = "storage"
)

// getCachesCmd represents the get caches command.
Expand Down Expand Up @@ -452,7 +454,7 @@ You can specify '-o wide' to display addition information.`,
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
return getCacheDetails(cmd, args, "access")
return getCacheDetails(cmd, args, access)
},
}

Expand All @@ -470,7 +472,7 @@ You can specify '-o wide' to display addition information.`,
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
return getCacheDetails(cmd, args, "storage")
return getCacheDetails(cmd, args, storage)
},
}

Expand Down Expand Up @@ -660,11 +662,11 @@ func getCacheDetails(cmd *cobra.Command, args []string, displayType string) erro
cmd.Printf("Cache: %s\n\n", args[0])
}

if displayType == "access" {
if displayType == access {
cmd.Println(FormatCacheDetailsSizeAndAccess(cacheDetails.Details))
} else if displayType == "index" {
cmd.Println(FormatCacheIndexDetails(cacheDetails.Details))
} else if displayType == "storage" {
} else if displayType == storage {
cmd.Println(FormatCacheDetailsStorage(cacheDetails.Details))
} else if displayType == partitionDisplayType {
cmd.Printf("Cache: %s\n", args[0])
Expand Down
4 changes: 4 additions & 0 deletions pkg/cmd/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ var (
machineParam string
rackParam string
siteParam string
roleParam string
skipMavenDepsParam bool
backupLogFilesParam bool
validPersistenceModes = []string{"on-demand", "active", "active-backup", "active-async"}
Expand Down Expand Up @@ -1456,6 +1457,7 @@ func init() {
createClusterCmd.Flags().StringVarP(&machineParam, machineArg, "", "", machineMessage)
createClusterCmd.Flags().StringVarP(&rackParam, rackArg, "", "", rackMessage)
createClusterCmd.Flags().StringVarP(&siteParam, siteArg, "", "", siteMessage)
createClusterCmd.Flags().StringVarP(&roleParam, roleArg, "", "", roleMessage)

stopClusterCmd.Flags().BoolVarP(&automaticallyConfirm, "yes", "y", false, confirmOptionMessage)

Expand All @@ -1474,6 +1476,7 @@ func init() {
startClusterCmd.Flags().StringVarP(&machineParam, machineArg, "", "", machineMessage)
startClusterCmd.Flags().StringVarP(&rackParam, rackArg, "", "", rackMessage)
startClusterCmd.Flags().StringVarP(&siteParam, siteArg, "", "", siteMessage)
startClusterCmd.Flags().StringVarP(&roleParam, roleArg, "", "", roleMessage)

startConsoleCmd.Flags().StringVarP(&heapMemoryParam, heapMemoryArg, "M", defaultHeap, heapMemoryMessage)
startConsoleCmd.Flags().Int32VarP(&logLevelParam, logLevelArg, "l", 5, logLevelMessage)
Expand Down Expand Up @@ -1505,6 +1508,7 @@ func init() {
scaleClusterCmd.Flags().StringVarP(&machineParam, machineArg, "", "", machineMessage)
scaleClusterCmd.Flags().StringVarP(&rackParam, rackArg, "", "", rackMessage)
scaleClusterCmd.Flags().StringVarP(&siteParam, siteArg, "", "", siteMessage)
scaleClusterCmd.Flags().StringVarP(&roleParam, roleArg, "", "", roleMessage)
}

// sanitizeConnectionName sanitizes a cluster connection
Expand Down
8 changes: 6 additions & 2 deletions pkg/cmd/cluster_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,10 @@ func getCacheServerArgs(connection ClusterConnection, member string, httpPort in
baseArgs = append(baseArgs, fmt.Sprintf("-Dcoherence.site=%s", siteParam))
}

if roleParam != "" {
baseArgs = append(baseArgs, fmt.Sprintf("-Dcoherence.role=%s", roleParam))
}

// if default heap is overridden, then use this
if heapMemoryParam != defaultHeap {
heap = heapMemoryParam
Expand Down Expand Up @@ -661,7 +665,7 @@ func runCommandBase(command, logFileName string, arguments []string) (string, er
Logger.Info("Run command", fields...)
}

start := time.Now()
startTime := time.Now()
process := exec.Command(command, arguments...)
if len(logFileName) > 0 {
// a log file was supplied, so we are assuming this command will be async and
Expand All @@ -684,7 +688,7 @@ func runCommandBase(command, logFileName string, arguments []string) (string, er

if Config.Debug {
fields := []zapcore.Field{
zap.String("time", fmt.Sprintf("%v", time.Since(start))),
zap.String("time", fmt.Sprintf("%v", time.Since(startTime))),
}
Logger.Info("Duration", fields...)
}
Expand Down
3 changes: 3 additions & 0 deletions pkg/cmd/formatting.go
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,9 @@ func FormatCacheDetailsStorage(cacheDetails []config.CacheDetail) string {
}

for _, value := range cacheDetails {
if value.Tier != "back" {
continue
}
var nodeID, _ = strconv.Atoi(value.NodeID)

table.AddRow(formatSmallInteger(int32(nodeID)), value.Tier,
Expand Down
4 changes: 2 additions & 2 deletions pkg/cmd/monitor_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -959,11 +959,11 @@ func getCacheContent(dataFetcher fetcher.Fetcher, displayType string) ([]string,
return emptyStringArray, err
}

if displayType == "access" {
if displayType == access {
sb.WriteString(FormatCacheDetailsSizeAndAccess(cacheDetails.Details))
} else if displayType == "index" {
sb.WriteString(FormatCacheIndexDetails(cacheDetails.Details))
} else if displayType == "storage" {
} else if displayType == storage {
sb.WriteString(FormatCacheDetailsStorage(cacheDetails.Details))
} else if displayType == partitionDisplayType {
sb.WriteString(FormatCachePartitions(cachePartitionDetails.Details, cacheSummary))
Expand Down
71 changes: 71 additions & 0 deletions pkg/cmd/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var (
validReporterAttributes = []string{reporterConfigFile, reporterCurrentBatch, reporterIntervalSeconds, reporterOutputPath}
reporterAttributeName string
reporterAttributeValue string
reporterNodID int
)

// getReportersCmd represents the get reporters command.
Expand Down Expand Up @@ -155,6 +156,73 @@ var describeReporterCmd = &cobra.Command{
},
}

// runReportCmd represents the run report command.
var runReportCmd = &cobra.Command{
Use: "report report-name",
Short: "run a report and return the output",
Long: `The 'run report' command runs a report on a specific node and returns the report output in JSON.
The report name should not include the .xml extension and will have the 'report' prefix added. E.g.
'report-node' will expand to 'reports/report-node.xml'. A HTTP 400 will be returned if the report name is not valid.`,
Args: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
displayErrorAndExit(cmd, "you must provide a report name")
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
var (
jsonData []byte
err error
dataFetcher fetcher.Fetcher
found = false
)

// retrieve the current context or the value from "-c"
_, dataFetcher, err = GetConnectionAndDataFetcher()
if err != nil {
return err
}

// validate the nodeID
nodeIDArray, err := GetClusterNodeIDs(dataFetcher)
if err != nil {
return err
}
for _, v := range nodeIDArray {
i, _ := strconv.Atoi(v)
if i == reporterNodID {
found = true
}
}
if !found {
return fmt.Errorf("unable to find node id %v", reporterNodID)
}

jsonData, err = dataFetcher.RunReportJSON(args[0], reporterNodID)
if err != nil {
return err
}

// output format cannot be table
if OutputFormat == constants.TABLE {
OutputFormat = constants.JSON
}

if strings.Contains(OutputFormat, constants.JSONPATH) {
jsonPathResult, err := utils.GetJSONPathResults(jsonData, OutputFormat)
if err != nil {
return err
}
cmd.Println(jsonPathResult)
return nil
} else if OutputFormat == constants.JSON {
cmd.Println(string(jsonData))
}

return nil
},
}

// startReporterCmd represents the start reporter command.
var startReporterCmd = &cobra.Command{
Use: reporterUse,
Expand Down Expand Up @@ -309,4 +377,7 @@ func init() {
_ = setReporterCmd.MarkFlagRequired("attribute")
setReporterCmd.Flags().StringVarP(&reporterAttributeValue, "value", "v", "", "attribute value to set")
_ = setReporterCmd.MarkFlagRequired("value")

runReportCmd.Flags().IntVarP(&reporterNodID, "node", "n", 0, "node to run report on")
_ = runReportCmd.MarkFlagRequired("node")
}
6 changes: 6 additions & 0 deletions pkg/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const (
machineMessage = "the machine name to use"
rackMessage = "the rack name to use"
siteMessage = "the site name to use"
roleMessage = "the role name to use"
cacheConfigMessage = "cache configuration file"
operationalConfigMessage = "override override file"
cacheConfigArg = "cache-config"
Expand All @@ -103,6 +104,7 @@ const (
machineArg = "machine"
rackArg = "rack"
siteArg = "site"
roleArg = "role"
logLevelMessage = "coherence log level"
profileMessage = "profile to add to cluster startup command line"
backupLogFilesMessage = "backup old cache server log files"
Expand Down Expand Up @@ -570,6 +572,10 @@ func Initialize(command *cobra.Command) *cobra.Command {
setCmd.AddCommand(setFederationCmd)
setCmd.AddCommand(setColorCmd)

// run command
command.AddCommand(runCmd)
runCmd.AddCommand(runReportCmd)

// clear
command.AddCommand(clearCmd)
clearCmd.AddCommand(clearContextCmd)
Expand Down
18 changes: 18 additions & 0 deletions pkg/cmd/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2024 Oracle and/or its affiliates.
* Licensed under the Universal Permissive License v 1.0 as shown at
* https://oss.oracle.com/licenses/upl.
*/

package cmd

import (
"github.com/spf13/cobra"
)

// runCmd represents the run.
var runCmd = &cobra.Command{
Use: "run",
Short: "run a report",
Long: `The 'run' command runs reports`,
}
3 changes: 3 additions & 0 deletions pkg/fetcher/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ type Fetcher interface {
// GetReporterJSON returns reporter for a node in raw json.
GetReporterJSON(nodeID string) ([]byte, error)

// RunReportJSON runs a specified report.
RunReportJSON(report string, nodeID int) ([]byte, error)

// StartReporter starts the reporter on a member.
StartReporter(nodeID string) error

Expand Down
9 changes: 9 additions & 0 deletions pkg/fetcher/http_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,15 @@ func (h HTTPFetcher) GetReporterJSON(nodeID string) ([]byte, error) {
return result, nil
}

// RunReportJSON runs a specified report.
func (h HTTPFetcher) RunReportJSON(report string, nodeID int) ([]byte, error) {
result, err := httpGetRequest(h, fmt.Sprintf("%s%d/runReport/%s%s", reportersPath, nodeID, report, links))
if err != nil {
return constants.EmptyByte, utils.GetError(fmt.Sprintf("cannot run report %v on node %v", report, nodeID), err)
}
return result, nil
}

// StartReporter starts the reporter on a member.
func (h HTTPFetcher) StartReporter(nodeID string) error {
_, err := issueReporterCommand(h, nodeID, "start")
Expand Down
4 changes: 1 addition & 3 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,7 @@ func IsValidInt(value string) bool {

// SanitizeSnapshotName sanitizes a snapshot name by replacing any unwanted characters with '-'.
func SanitizeSnapshotName(snapshotName string) string {
var (
sb = strings.Builder{}
)
var sb = strings.Builder{}

for _, c := range []byte(snapshotName) {
r := rune(c)
Expand Down
1 change: 1 addition & 0 deletions scripts/generate-doc-snippets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ create_doc $DOCS_DIR/describe_reporter "${COHCTL} describe reporter --help"
create_doc $DOCS_DIR/start_reporter "${COHCTL} start reporter --help"
create_doc $DOCS_DIR/stop_reporter "${COHCTL} stop reporter --help"
create_doc $DOCS_DIR/set_reporter "${COHCTL} set reporter --help"
create_doc $DOCS_DIR/run_report "${COHCTL} run report --help"

# JFRs
create_doc $DOCS_DIR/get_jfrs "${COHCTL} get jfrs --help"
Expand Down

0 comments on commit 4fe680c

Please sign in to comment.