Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli/start: use the same format for server details in multi-tenant #73676

Merged
merged 2 commits into from
Dec 10, 2021
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 docs/generated/redact_safe.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pkg/roachpb/metadata.go | `ReplicaID`
pkg/roachpb/metadata.go | `ReplicaType`
pkg/roachpb/metadata.go | `StoreID`
pkg/roachpb/method.go | `Method`
pkg/roachpb/tenant.go | `TenantID`
pkg/rpc/connection_class.go | `ConnectionClass`
pkg/sql/catalog/descpb/structured.go | `ColumnID`
pkg/sql/catalog/descpb/structured.go | `ConstraintType`
Expand Down
11 changes: 9 additions & 2 deletions pkg/cli/mt_start_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/settings/cluster"
"github.com/cockroachdb/cockroach/pkg/util/log"
"github.com/cockroachdb/cockroach/pkg/util/sdnotify"
"github.com/cockroachdb/cockroach/pkg/util/timeutil"
"github.com/cockroachdb/errors"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -62,6 +63,8 @@ well unless it can be verified using a trusted root certificate store. That is,
}

func runStartSQL(cmd *cobra.Command, args []string) error {
tBegin := timeutil.Now()

// First things first: if the user wants background processing,
// relinquish the terminal ASAP by forking and exiting.
//
Expand Down Expand Up @@ -108,7 +111,7 @@ func runStartSQL(cmd *cobra.Command, args []string) error {

initGEOS(ctx)

sqlServer, addr, httpAddr, err := server.StartTenant(
sqlServer, _, _, err := server.StartTenant(
ctx,
stopper,
clusterName,
Expand Down Expand Up @@ -145,7 +148,11 @@ func runStartSQL(cmd *cobra.Command, args []string) error {
sqlServer.StartDiagnostics(ctx)
}

log.Infof(ctx, "SQL server for tenant %s listening at %s, http at %s", serverCfg.SQLConfig.TenantID, addr, httpAddr)
// Report the server identifiers and other server details
// in the same format as 'cockroach start'.
if err := reportServerInfo(ctx, tBegin, &serverCfg, st, false /* isHostNode */, false /* initialStart */); err != nil {
return err
}

// TODO(tbg): make the other goodies in `./cockroach start` reusable, such as
// logging to files, periodic memory output, heap and goroutine dumps, debug
Expand Down
206 changes: 123 additions & 83 deletions pkg/cli/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -676,93 +676,15 @@ If problems persist, please see %s.`
return err
}

// Now inform the user that the server is running and tell the
// user about its run-time derived parameters.
var buf redact.StringBuilder
info := build.GetInfo()
buf.Printf("CockroachDB node starting at %s (took %0.1fs)\n", timeutil.Now(), timeutil.Since(tBegin).Seconds())
buf.Printf("build:\t%s %s @ %s (%s)\n",
redact.Safe(info.Distribution), redact.Safe(info.Tag), redact.Safe(info.Time), redact.Safe(info.GoVersion))
buf.Printf("webui:\t%s\n", serverCfg.AdminURL())

// (Re-)compute the client connection URL. We cannot do this
// earlier (e.g. above, in the runStart function) because
// at this time the address and port have not been resolved yet.
sCtx := rpc.MakeSecurityContext(serverCfg.Config, security.ClusterTLSSettings(serverCfg.Settings), roachpb.SystemTenantID)
pgURL, err := sCtx.PGURL(url.User(security.RootUser))
if err != nil {
log.Ops.Errorf(ctx, "failed computing the URL: %v", err)
return err
}
buf.Printf("sql:\t%s\n", pgURL.ToPQ())
buf.Printf("sql (JDBC):\t%s\n", pgURL.ToJDBC())

buf.Printf("RPC client flags:\t%s\n", clientFlagsRPC())
if len(serverCfg.SocketFile) != 0 {
buf.Printf("socket:\t%s\n", serverCfg.SocketFile)
}
logNum := 1
_ = cliCtx.logConfig.IterateDirectories(func(d string) error {
if logNum == 1 {
// Backward-compatibility.
buf.Printf("logs:\t%s\n", d)
} else {
buf.Printf("logs[%d]:\t%s\n", logNum, d)
}
logNum++
return nil
})
if serverCfg.Attrs != "" {
buf.Printf("attrs:\t%s\n", serverCfg.Attrs)
}
if len(serverCfg.Locality.Tiers) > 0 {
buf.Printf("locality:\t%s\n", serverCfg.Locality)
}
if s.TempDir() != "" {
buf.Printf("temp dir:\t%s\n", s.TempDir())
}
if ext := s.ClusterSettings().ExternalIODir; ext != "" {
buf.Printf("external I/O path: \t%s\n", ext)
} else {
buf.Printf("external I/O path: \t<disabled>\n")
}
for i, spec := range serverCfg.Stores.Specs {
buf.Printf("store[%d]:\t%s\n", i, spec)
}
buf.Printf("storage engine: \t%s\n", &serverCfg.StorageEngine)
// Remember the server identifiers for logging.
// TODO(knz): Remove this.
nodeID := s.NodeID()
if initialStart {
if nodeID == kvserver.FirstNodeID {
buf.Printf("status:\tinitialized new cluster\n")
} else {
buf.Printf("status:\tinitialized new node, joined pre-existing cluster\n")
}
} else {
buf.Printf("status:\trestarted pre-existing node\n")
}

if baseCfg.ClusterName != "" {
buf.Printf("cluster name:\t%s\n", baseCfg.ClusterName)
}

// Remember the cluster ID for log file rotation.
clusterID := s.ClusterID().String()
log.SetNodeIDs(clusterID, int32(nodeID))
buf.Printf("clusterID:\t%s\n", clusterID)
buf.Printf("nodeID:\t%d\n", nodeID)

// Collect the formatted string and show it to the user.
msg, err := expandTabsInRedactableBytes(buf.RedactableBytes())
if err != nil {
return err
}
msgS := msg.ToString()
log.Ops.Infof(ctx, "node startup completed:\n%s", msgS)
if !startCtx.inBackground && !log.LoggingToStderr(severity.INFO) {
fmt.Print(msgS.StripMarkers())
}

return nil
// Now inform the user that the server is running and tell the
// user about its run-time derived parameters.
return reportServerInfo(ctx, tBegin, &serverCfg, s.ClusterSettings(), true /* isHostNode */, initialStart)
}(); err != nil {
errChan <- err
}
Expand Down Expand Up @@ -958,6 +880,124 @@ If problems persist, please see %s.`
return returnErr
}

// reportServerInfo prints out the server version and network details
// in a standardized format.
func reportServerInfo(
ctx context.Context,
startTime time.Time,
serverCfg *server.Config,
st *cluster.Settings,
isHostNode, initialStart bool,
) error {
srvS := redact.SafeString("SQL server")
if isHostNode {
srvS = "node"
}

var buf redact.StringBuilder
info := build.GetInfo()
buf.Printf("CockroachDB %s starting at %s (took %0.1fs)\n", srvS, timeutil.Now(), timeutil.Since(startTime).Seconds())
buf.Printf("build:\t%s %s @ %s (%s)\n",
redact.Safe(info.Distribution), redact.Safe(info.Tag), redact.Safe(info.Time), redact.Safe(info.GoVersion))
buf.Printf("webui:\t%s\n", serverCfg.AdminURL())

// (Re-)compute the client connection URL. We cannot do this
// earlier (e.g. above, in the runStart function) because
// at this time the address and port have not been resolved yet.
sCtx := rpc.MakeSecurityContext(serverCfg.Config, security.ClusterTLSSettings(serverCfg.Settings), roachpb.SystemTenantID)
pgURL, err := sCtx.PGURL(url.User(security.RootUser))
if err != nil {
log.Ops.Errorf(ctx, "failed computing the URL: %v", err)
return err
}
buf.Printf("sql:\t%s\n", pgURL.ToPQ())
buf.Printf("sql (JDBC):\t%s\n", pgURL.ToJDBC())

buf.Printf("RPC client flags:\t%s\n", clientFlagsRPC())
if len(serverCfg.SocketFile) != 0 {
buf.Printf("socket:\t%s\n", serverCfg.SocketFile)
}
logNum := 1
_ = cliCtx.logConfig.IterateDirectories(func(d string) error {
if logNum == 1 {
// Backward-compatibility.
buf.Printf("logs:\t%s\n", d)
} else {
buf.Printf("logs[%d]:\t%s\n", logNum, d)
}
logNum++
return nil
})
if serverCfg.Attrs != "" {
buf.Printf("attrs:\t%s\n", serverCfg.Attrs)
}
if len(serverCfg.Locality.Tiers) > 0 {
buf.Printf("locality:\t%s\n", serverCfg.Locality)
}
if tmpDir := serverCfg.SQLConfig.TempStorageConfig.Path; tmpDir != "" {
buf.Printf("temp dir:\t%s\n", tmpDir)
}
if ext := st.ExternalIODir; ext != "" {
buf.Printf("external I/O path: \t%s\n", ext)
} else {
buf.Printf("external I/O path: \t<disabled>\n")
}
for i, spec := range serverCfg.Stores.Specs {
buf.Printf("store[%d]:\t%s\n", i, spec)
}
buf.Printf("storage engine: \t%s\n", &serverCfg.StorageEngine)

// Print the commong server identifiers.
if baseCfg.ClusterName != "" {
buf.Printf("cluster name:\t%s\n", baseCfg.ClusterName)
}
clusterID := serverCfg.BaseConfig.ClusterIDContainer.Get().String()
buf.Printf("clusterID:\t%s\n", clusterID)

nodeID := serverCfg.BaseConfig.IDContainer.Get()
if isHostNode {
if initialStart {
if nodeID == kvserver.FirstNodeID {
buf.Printf("status:\tinitialized new cluster\n")
} else {
buf.Printf("status:\tinitialized new node, joined pre-existing cluster\n")
}
} else {
buf.Printf("status:\trestarted pre-existing node\n")
}
// Report the server identifiers.
buf.Printf("nodeID:\t%d\n", nodeID)
} else {
// Report the SQL server identifiers.
buf.Printf("tenantID:\t%s\n", serverCfg.SQLConfig.TenantID)
buf.Printf("instanceID:\t%d\n", nodeID)

if kvAddrs := serverCfg.SQLConfig.TenantKVAddrs; len(kvAddrs) > 0 {
// Report which KV servers are connected.
buf.Printf("KV addresses:\t")
comma := redact.SafeString("")
for _, addr := range serverCfg.SQLConfig.TenantKVAddrs {
buf.Printf("%s%s", comma, addr)
comma = ", "
}
buf.Printf("\n")
}
}

// Collect the formatted string and show it to the user.
msg, err := expandTabsInRedactableBytes(buf.RedactableBytes())
if err != nil {
return err
}
msgS := msg.ToString()
log.Ops.Infof(ctx, "%s startup completed:\n%s", srvS, msgS)
if !startCtx.inBackground && !log.LoggingToStderr(severity.INFO) {
fmt.Print(msgS.StripMarkers())
}

return nil
}

// expandTabsInRedactableBytes expands tabs in the redactable byte
// slice, so that columns are aligned. The correctness of this
// function depends on the assumption that the `tabwriter` does not
Expand Down
3 changes: 3 additions & 0 deletions pkg/roachpb/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ func (t TenantID) String() string {
}
}

// SafeValue implements the redact.SafeValue interface.
func (t TenantID) SafeValue() {}

// Protects against zero value.
func checkValid(id uint64) {
if id == 0 {
Expand Down
1 change: 1 addition & 0 deletions pkg/server/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ func makeTenantSQLServerArgs(
rpcContext := rpc.NewContext(rpc.ContextOptions{
TenantID: sqlCfg.TenantID,
NodeID: baseCfg.IDContainer,
ClusterID: baseCfg.ClusterIDContainer,
AmbientCtx: baseCfg.AmbientCtx,
Config: baseCfg.Config,
Clock: clock,
Expand Down