From b8ae4a42bf14c98b6f3d10b4396a6b6185e3da9d Mon Sep 17 00:00:00 2001 From: Will Lahti Date: Mon, 24 Oct 2016 16:00:25 -0400 Subject: [PATCH] Add CLI to set/get module log levels on peer Dynamically set or get the log level for the specified module running on a peer. Useful for problem determination / debugging. Use the following format: peer logging setlevel peer logging getlevel Fix Issue FAB-574 Change-Id: I5b16d100a84393bafe052511bb2e6f188214e81e Signed-off-by: Will Lahti --- core/admin.go | 17 +++++ flogging/logging.go | 30 ++++++++ flogging/logging_test.go | 43 +++++++++++ peer/clilogging/common.go | 47 ++++++++++++ peer/clilogging/getlevel.go | 66 ++++++++++++++++ peer/clilogging/logging.go | 42 +++++++++++ peer/clilogging/logging_test.go | 98 ++++++++++++++++++++++++ peer/clilogging/setlevel.go | 67 +++++++++++++++++ peer/main.go | 2 + protos/api.pb.go | 2 + protos/server_admin.pb.go | 128 +++++++++++++++++++++++++++----- protos/server_admin.proto | 11 +++ 12 files changed, 536 insertions(+), 17 deletions(-) create mode 100644 peer/clilogging/common.go create mode 100644 peer/clilogging/getlevel.go create mode 100644 peer/clilogging/logging.go create mode 100644 peer/clilogging/logging_test.go create mode 100644 peer/clilogging/setlevel.go diff --git a/core/admin.go b/core/admin.go index 2fa31debf70..fafd12c0807 100644 --- a/core/admin.go +++ b/core/admin.go @@ -25,6 +25,7 @@ import ( "golang.org/x/net/context" "github.com/golang/protobuf/ptypes/empty" + "github.com/hyperledger/fabric/flogging" pb "github.com/hyperledger/fabric/protos" ) @@ -78,3 +79,19 @@ func (*ServerAdmin) StopServer(context.Context, *empty.Empty) (*pb.ServerStatus, defer os.Exit(0) return status, nil } + +// GetModuleLogLevel gets the current logging level for the specified module +func (*ServerAdmin) GetModuleLogLevel(ctx context.Context, request *pb.LogLevelRequest) (*pb.LogLevelResponse, error) { + logLevelString, err := flogging.GetModuleLogLevel(request.LogModule) + logResponse := &pb.LogLevelResponse{LogModule: request.LogModule, LogLevel: logLevelString} + + return logResponse, err +} + +// SetModuleLogLevel sets the logging level for the specified module +func (*ServerAdmin) SetModuleLogLevel(ctx context.Context, request *pb.LogLevelRequest) (*pb.LogLevelResponse, error) { + logLevelString, err := flogging.SetModuleLogLevel(request.LogModule, request.LogLevel) + logResponse := &pb.LogLevelResponse{LogModule: request.LogModule, LogLevel: logLevelString} + + return logResponse, err +} diff --git a/flogging/logging.go b/flogging/logging.go index f2e93a615ce..b66285c403c 100644 --- a/flogging/logging.go +++ b/flogging/logging.go @@ -98,3 +98,33 @@ func init() { backendFormatter := logging.NewBackendFormatter(backend, format) logging.SetBackend(backendFormatter).SetLevel(loggingDefaultLevel, "") } + +// GetModuleLogLevel gets the current logging level for the specified module +func GetModuleLogLevel(module string) (string, error) { + // logging.GetLevel() returns the logging level for the module, if defined. + // otherwise, it returns the default logging level, as set by + // flogging/logging.go + level := logging.GetLevel(module).String() + + loggingLogger.Infof("Module '%s' logger enabled for log level: %s", module, level) + + return level, nil +} + +// SetModuleLogLevel sets the logging level for the specified module. This is +// currently only called from admin.go but can be called from anywhere in the +// code on a running peer to dynamically change the log level for the module. +func SetModuleLogLevel(module string, logLevel string) (string, error) { + level, err := logging.LogLevel(logLevel) + + if err != nil { + loggingLogger.Warningf("Invalid logging level: %s - ignored", logLevel) + } else { + logging.SetLevel(logging.Level(level), module) + loggingLogger.Infof("Module '%s' logger enabled for log level: %s", module, level) + } + + logLevelString := level.String() + + return logLevelString, err +} diff --git a/flogging/logging_test.go b/flogging/logging_test.go index 000320b534f..5587a322ac9 100644 --- a/flogging/logging_test.go +++ b/flogging/logging_test.go @@ -143,6 +143,49 @@ func TestLoggingLevelInvalidModuleSyntax(t *testing.T) { assertDefaultLoggingLevel(t, flogging.DefaultLoggingLevel()) } +func TestGetModuleLoggingLevelDefault(t *testing.T) { + level, _ := flogging.GetModuleLogLevel("peer") + + // peer should be using the default log level at this point + if level != "INFO" { + t.FailNow() + } +} + +func TestGetModuleLoggingLevelDebug(t *testing.T) { + flogging.SetModuleLogLevel("peer", "DEBUG") + level, _ := flogging.GetModuleLogLevel("peer") + + // ensure that the log level has changed to debug + if level != "DEBUG" { + t.FailNow() + } +} + +func TestGetModuleLoggingLevelInvalid(t *testing.T) { + flogging.SetModuleLogLevel("peer", "invalid") + level, _ := flogging.GetModuleLogLevel("peer") + + // ensure that the log level didn't change after invalid log level specified + if level != "DEBUG" { + t.FailNow() + } +} + +func TestSetModuleLoggingLevel(t *testing.T) { + flogging.SetModuleLogLevel("peer", "WARNING") + + // ensure that the log level has changed to warning + assertModuleLoggingLevel(t, "peer", logging.WARNING) +} + +func TestSetModuleLoggingLevelInvalid(t *testing.T) { + flogging.SetModuleLogLevel("peer", "invalid") + + // ensure that the log level didn't change after invalid log level specified + assertModuleLoggingLevel(t, "peer", logging.WARNING) +} + func assertDefaultLoggingLevel(t *testing.T, expectedLevel logging.Level) { assertModuleLoggingLevel(t, "", expectedLevel) } diff --git a/peer/clilogging/common.go b/peer/clilogging/common.go new file mode 100644 index 00000000000..dfc16036363 --- /dev/null +++ b/peer/clilogging/common.go @@ -0,0 +1,47 @@ +/* +Copyright IBM Corp. 2016 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package clilogging + +import ( + "fmt" + + "github.com/op/go-logging" + "github.com/spf13/cobra" +) + +func checkLoggingCmdParams(cmd *cobra.Command, args []string) error { + var err error + + // check that at least one parameter is passed in + if len(args) == 0 { + return fmt.Errorf("no parameters provided") + } + + if cmd.Name() == "setlevel" { + if len(args) == 1 { + err = fmt.Errorf("no log level provided") + } else { + // check that log level is valid. if not, err is set + _, err = logging.LogLevel(args[1]) + if err != nil { + err = fmt.Errorf("%s - %s", err, args[1]) + } + } + } + + return err +} diff --git a/peer/clilogging/getlevel.go b/peer/clilogging/getlevel.go new file mode 100644 index 00000000000..3c690f97026 --- /dev/null +++ b/peer/clilogging/getlevel.go @@ -0,0 +1,66 @@ +/* +Copyright IBM Corp. 2016 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package clilogging + +import ( + "fmt" + + "github.com/hyperledger/fabric/core/peer" + pb "github.com/hyperledger/fabric/protos" + "github.com/spf13/cobra" + "golang.org/x/net/context" +) + +func getLevelCmd() *cobra.Command { + return loggingGetLevelCmd +} + +var loggingGetLevelCmd = &cobra.Command{ + Use: "getlevel ", + Short: "Returns the logging level of the requested module logger.", + Long: `Returns the logging level of the requested module logger`, + Run: func(cmd *cobra.Command, args []string) { + getLevel(cmd, args) + }, +} + +func getLevel(cmd *cobra.Command, args []string) (err error) { + err = checkLoggingCmdParams(cmd, args) + + if err != nil { + logger.Warningf("Error: %s", err) + } else { + clientConn, err := peer.NewPeerClientConnection() + if err != nil { + logger.Infof("Error trying to connect to local peer: %s", err) + err = fmt.Errorf("Error trying to connect to local peer: %s", err) + fmt.Println(&pb.ServerStatus{Status: pb.ServerStatus_UNKNOWN}) + return err + } + + serverClient := pb.NewAdminClient(clientConn) + + logResponse, err := serverClient.GetModuleLogLevel(context.Background(), &pb.LogLevelRequest{LogModule: args[0]}) + + if err != nil { + logger.Warningf("Error retrieving log level") + return err + } + logger.Infof("Current log level for module '%s': %s", logResponse.LogModule, logResponse.LogLevel) + } + return err +} diff --git a/peer/clilogging/logging.go b/peer/clilogging/logging.go new file mode 100644 index 00000000000..c1522fee394 --- /dev/null +++ b/peer/clilogging/logging.go @@ -0,0 +1,42 @@ +/* +Copyright IBM Corp. 2016 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package clilogging + +import ( + "fmt" + + "github.com/op/go-logging" + "github.com/spf13/cobra" +) + +const loggingFuncName = "logging" + +var logger = logging.MustGetLogger("loggingCmd") + +// Cmd returns the cobra command for Logging +func Cmd() *cobra.Command { + loggingCmd.AddCommand(getLevelCmd()) + loggingCmd.AddCommand(setLevelCmd()) + + return loggingCmd +} + +var loggingCmd = &cobra.Command{ + Use: loggingFuncName, + Short: fmt.Sprintf("%s specific commands.", loggingFuncName), + Long: fmt.Sprintf("%s specific commands.", loggingFuncName), +} diff --git a/peer/clilogging/logging_test.go b/peer/clilogging/logging_test.go new file mode 100644 index 00000000000..5ee333973f6 --- /dev/null +++ b/peer/clilogging/logging_test.go @@ -0,0 +1,98 @@ +/* + Copyright Digital Asset Holdings, LLC 2016 All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package clilogging + +import "testing" + +// TestGetLevelEmptyParams tests the parameter checking for getlevel, which +// should return an error when no parameters are provided +func TestGetLevelEmptyParams(t *testing.T) { + var args []string + + err := checkLoggingCmdParams(getLevelCmd(), args) + + if err == nil { + t.FailNow() + } +} + +// TestGetLevel tests the parameter checking for getlevel, which should +// should return a nil error when one (or more) parameters are provided +func TestGetLevel(t *testing.T) { + args := make([]string, 1) + args[0] = "peer" + + err := checkLoggingCmdParams(getLevelCmd(), args) + + if err != nil { + t.FailNow() + } +} + +// TestSetLevelEmptyParams tests the parameter checking for setlevel, which +// should return an error when no parameters are provided +func TestSetLevelEmptyParams(t *testing.T) { + var args []string + + err := checkLoggingCmdParams(setLevelCmd(), args) + + if err == nil { + t.FailNow() + } +} + +// TestSetLevelEmptyParams tests the parameter checking for setlevel, which +// should return an error when only one parameter is provided +func TestSetLevelOneParam(t *testing.T) { + args := make([]string, 1) + args[0] = "peer" + + err := checkLoggingCmdParams(setLevelCmd(), args) + + if err == nil { + t.FailNow() + } +} + +// TestSetLevelEmptyParams tests the parameter checking for setlevel, which +// should return an error when an invalid log level is provided +func TestSetLevelInvalid(t *testing.T) { + args := make([]string, 2) + args[0] = "peer" + args[1] = "invalidlevel" + + err := checkLoggingCmdParams(setLevelCmd(), args) + + if err == nil { + t.FailNow() + } +} + +// TestSetLevelEmptyParams tests the parameter checking for setlevel, which +// should return a nil error when two parameters, the second of which is a +// valid log level, are provided +func TestSetLevel(t *testing.T) { + args := make([]string, 2) + args[0] = "peer" + args[1] = "debug" + + err := checkLoggingCmdParams(setLevelCmd(), args) + + if err != nil { + t.FailNow() + } +} diff --git a/peer/clilogging/setlevel.go b/peer/clilogging/setlevel.go new file mode 100644 index 00000000000..f5670e261b1 --- /dev/null +++ b/peer/clilogging/setlevel.go @@ -0,0 +1,67 @@ +/* +Copyright IBM Corp. 2016 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package clilogging + +import ( + "fmt" + + "golang.org/x/net/context" + + "github.com/hyperledger/fabric/core/peer" + pb "github.com/hyperledger/fabric/protos" + "github.com/spf13/cobra" +) + +func setLevelCmd() *cobra.Command { + return loggingSetLevelCmd +} + +var loggingSetLevelCmd = &cobra.Command{ + Use: "setlevel ", + Short: "Sets the logging level of the requested module logger.", + Long: `Sets the logging level of the requested module logger`, + Run: func(cmd *cobra.Command, args []string) { + setLevel(cmd, args) + }, +} + +func setLevel(cmd *cobra.Command, args []string) (err error) { + err = checkLoggingCmdParams(cmd, args) + + if err != nil { + logger.Warningf("Error: %s", err) + } else { + clientConn, err := peer.NewPeerClientConnection() + if err != nil { + logger.Infof("Error trying to connect to local peer: %s", err) + err = fmt.Errorf("Error trying to connect to local peer: %s", err) + fmt.Println(&pb.ServerStatus{Status: pb.ServerStatus_UNKNOWN}) + return err + } + + serverClient := pb.NewAdminClient(clientConn) + + logResponse, err := serverClient.SetModuleLogLevel(context.Background(), &pb.LogLevelRequest{LogModule: args[0], LogLevel: args[1]}) + + if err != nil { + logger.Warningf("Invalid log level: %s", args[1]) + return err + } + logger.Infof("Log level set for module '%s': %s", logResponse.LogModule, logResponse.LogLevel) + } + return err +} diff --git a/peer/main.go b/peer/main.go index cecc0e7f4b3..0c8b2c09049 100644 --- a/peer/main.go +++ b/peer/main.go @@ -33,6 +33,7 @@ import ( "github.com/hyperledger/fabric/core/crypto" "github.com/hyperledger/fabric/flogging" "github.com/hyperledger/fabric/peer/chaincode" + "github.com/hyperledger/fabric/peer/clilogging" "github.com/hyperledger/fabric/peer/network" "github.com/hyperledger/fabric/peer/node" "github.com/hyperledger/fabric/peer/version" @@ -109,6 +110,7 @@ func main() { mainCmd.AddCommand(node.Cmd()) mainCmd.AddCommand(network.Cmd()) mainCmd.AddCommand(chaincode.Cmd()) + mainCmd.AddCommand(clilogging.Cmd()) runtime.GOMAXPROCS(viper.GetInt("peer.gomaxprocs")) diff --git a/protos/api.pb.go b/protos/api.pb.go index 82464121e50..abf6f5f3d3a 100644 --- a/protos/api.pb.go +++ b/protos/api.pb.go @@ -92,6 +92,8 @@ It has these top-level messages: Transaction2 TransactionAction ServerStatus + LogLevelRequest + LogLevelResponse */ package protos diff --git a/protos/server_admin.pb.go b/protos/server_admin.pb.go index 22c4f0b4d92..8b001d1b5e3 100644 --- a/protos/server_admin.pb.go +++ b/protos/server_admin.pb.go @@ -61,8 +61,30 @@ func (m *ServerStatus) String() string { return proto.CompactTextStri func (*ServerStatus) ProtoMessage() {} func (*ServerStatus) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{0} } +type LogLevelRequest struct { + LogModule string `protobuf:"bytes,1,opt,name=logModule" json:"logModule,omitempty"` + LogLevel string `protobuf:"bytes,2,opt,name=logLevel" json:"logLevel,omitempty"` +} + +func (m *LogLevelRequest) Reset() { *m = LogLevelRequest{} } +func (m *LogLevelRequest) String() string { return proto.CompactTextString(m) } +func (*LogLevelRequest) ProtoMessage() {} +func (*LogLevelRequest) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{1} } + +type LogLevelResponse struct { + LogModule string `protobuf:"bytes,1,opt,name=logModule" json:"logModule,omitempty"` + LogLevel string `protobuf:"bytes,2,opt,name=logLevel" json:"logLevel,omitempty"` +} + +func (m *LogLevelResponse) Reset() { *m = LogLevelResponse{} } +func (m *LogLevelResponse) String() string { return proto.CompactTextString(m) } +func (*LogLevelResponse) ProtoMessage() {} +func (*LogLevelResponse) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{2} } + func init() { proto.RegisterType((*ServerStatus)(nil), "protos.ServerStatus") + proto.RegisterType((*LogLevelRequest)(nil), "protos.LogLevelRequest") + proto.RegisterType((*LogLevelResponse)(nil), "protos.LogLevelResponse") proto.RegisterEnum("protos.ServerStatus_StatusCode", ServerStatus_StatusCode_name, ServerStatus_StatusCode_value) } @@ -81,6 +103,8 @@ type AdminClient interface { GetStatus(ctx context.Context, in *google_protobuf1.Empty, opts ...grpc.CallOption) (*ServerStatus, error) StartServer(ctx context.Context, in *google_protobuf1.Empty, opts ...grpc.CallOption) (*ServerStatus, error) StopServer(ctx context.Context, in *google_protobuf1.Empty, opts ...grpc.CallOption) (*ServerStatus, error) + GetModuleLogLevel(ctx context.Context, in *LogLevelRequest, opts ...grpc.CallOption) (*LogLevelResponse, error) + SetModuleLogLevel(ctx context.Context, in *LogLevelRequest, opts ...grpc.CallOption) (*LogLevelResponse, error) } type adminClient struct { @@ -118,6 +142,24 @@ func (c *adminClient) StopServer(ctx context.Context, in *google_protobuf1.Empty return out, nil } +func (c *adminClient) GetModuleLogLevel(ctx context.Context, in *LogLevelRequest, opts ...grpc.CallOption) (*LogLevelResponse, error) { + out := new(LogLevelResponse) + err := grpc.Invoke(ctx, "/protos.Admin/GetModuleLogLevel", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminClient) SetModuleLogLevel(ctx context.Context, in *LogLevelRequest, opts ...grpc.CallOption) (*LogLevelResponse, error) { + out := new(LogLevelResponse) + err := grpc.Invoke(ctx, "/protos.Admin/SetModuleLogLevel", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for Admin service type AdminServer interface { @@ -125,6 +167,8 @@ type AdminServer interface { GetStatus(context.Context, *google_protobuf1.Empty) (*ServerStatus, error) StartServer(context.Context, *google_protobuf1.Empty) (*ServerStatus, error) StopServer(context.Context, *google_protobuf1.Empty) (*ServerStatus, error) + GetModuleLogLevel(context.Context, *LogLevelRequest) (*LogLevelResponse, error) + SetModuleLogLevel(context.Context, *LogLevelRequest) (*LogLevelResponse, error) } func RegisterAdminServer(s *grpc.Server, srv AdminServer) { @@ -185,6 +229,42 @@ func _Admin_StopServer_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Admin_GetModuleLogLevel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LogLevelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServer).GetModuleLogLevel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/protos.Admin/GetModuleLogLevel", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServer).GetModuleLogLevel(ctx, req.(*LogLevelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Admin_SetModuleLogLevel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LogLevelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServer).SetModuleLogLevel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/protos.Admin/SetModuleLogLevel", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServer).SetModuleLogLevel(ctx, req.(*LogLevelRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Admin_serviceDesc = grpc.ServiceDesc{ ServiceName: "protos.Admin", HandlerType: (*AdminServer)(nil), @@ -201,6 +281,14 @@ var _Admin_serviceDesc = grpc.ServiceDesc{ MethodName: "StopServer", Handler: _Admin_StopServer_Handler, }, + { + MethodName: "GetModuleLogLevel", + Handler: _Admin_GetModuleLogLevel_Handler, + }, + { + MethodName: "SetModuleLogLevel", + Handler: _Admin_SetModuleLogLevel_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: fileDescriptor15, @@ -209,21 +297,27 @@ var _Admin_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("server_admin.proto", fileDescriptor15) } var fileDescriptor15 = []byte{ - // 253 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0x2a, 0x4e, 0x2d, 0x2a, - 0x4b, 0x2d, 0x8a, 0x4f, 0x4c, 0xc9, 0xcd, 0xcc, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, - 0x03, 0x53, 0xc5, 0x52, 0xd2, 0xe9, 0xf9, 0xf9, 0xe9, 0x39, 0xa9, 0xfa, 0x60, 0x6e, 0x52, 0x69, - 0x9a, 0x7e, 0x6a, 0x6e, 0x41, 0x49, 0x25, 0x44, 0x91, 0xd2, 0x22, 0x46, 0x2e, 0x9e, 0x60, 0xb0, - 0xde, 0xe0, 0x92, 0xc4, 0x92, 0xd2, 0x62, 0x21, 0x73, 0x2e, 0xb6, 0x62, 0x30, 0x4b, 0x82, 0x51, - 0x81, 0x51, 0x83, 0xcf, 0x48, 0x1e, 0xa2, 0xb0, 0x58, 0x0f, 0x59, 0x95, 0x1e, 0x84, 0x72, 0xce, - 0x4f, 0x49, 0x0d, 0x82, 0x2a, 0x57, 0x8a, 0xe4, 0xe2, 0x42, 0x88, 0x0a, 0xf1, 0x72, 0x71, 0x86, - 0xfa, 0xb9, 0xb8, 0xba, 0x79, 0xfa, 0xb9, 0xba, 0x08, 0x30, 0x08, 0x71, 0x73, 0xb1, 0x07, 0x87, - 0x38, 0x06, 0x85, 0xb8, 0xba, 0x08, 0x30, 0x42, 0x38, 0xfe, 0x01, 0x01, 0xae, 0x2e, 0x02, 0x4c, - 0x42, 0x5c, 0x5c, 0x6c, 0x01, 0x8e, 0xa1, 0xc1, 0xae, 0x2e, 0x02, 0xcc, 0x42, 0x9c, 0x5c, 0xac, - 0xae, 0x41, 0x41, 0xfe, 0x41, 0x02, 0x2c, 0x20, 0x35, 0xa1, 0x7e, 0xde, 0x7e, 0xfe, 0xe1, 0x7e, - 0x02, 0xac, 0x46, 0x07, 0x19, 0xb9, 0x58, 0x1d, 0x41, 0x3e, 0x13, 0xb2, 0xe6, 0xe2, 0x74, 0x4f, - 0x2d, 0x81, 0x3a, 0x55, 0x4c, 0x0f, 0xe2, 0x33, 0x3d, 0x98, 0xcf, 0xf4, 0x5c, 0x41, 0x3e, 0x93, - 0x12, 0xc1, 0xe6, 0x64, 0x25, 0x06, 0x21, 0x5b, 0x2e, 0xee, 0xe0, 0x92, 0xc4, 0xa2, 0x12, 0x88, - 0x30, 0xc9, 0xda, 0x6d, 0x40, 0x1e, 0xcc, 0x2f, 0x20, 0x4f, 0x77, 0x12, 0x24, 0x36, 0x8c, 0x01, - 0x01, 0x00, 0x00, 0xff, 0xff, 0x5b, 0x2d, 0xff, 0xc2, 0xaa, 0x01, 0x00, 0x00, + // 340 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x92, 0xcf, 0x4e, 0xc2, 0x40, + 0x10, 0xc6, 0x29, 0x0a, 0xda, 0xc1, 0x3f, 0xeb, 0xc6, 0x28, 0xa9, 0x26, 0x9a, 0x9e, 0x3c, 0x95, + 0x04, 0x0f, 0x1e, 0xd4, 0x03, 0xb1, 0x2b, 0x1a, 0xb0, 0x90, 0x2d, 0xc4, 0x78, 0x32, 0x10, 0xc6, + 0xc6, 0xa4, 0xb0, 0xb5, 0xbb, 0x25, 0xf1, 0x75, 0x7c, 0x27, 0xdf, 0xc7, 0x74, 0x17, 0xc4, 0xa8, + 0x17, 0x89, 0xa7, 0xd9, 0x99, 0xf9, 0xbe, 0x2f, 0xbb, 0xbf, 0x2c, 0x50, 0x89, 0xe9, 0x14, 0xd3, + 0xc7, 0xc1, 0x68, 0xfc, 0x3c, 0xf1, 0x92, 0x54, 0x28, 0x41, 0xcb, 0xba, 0x48, 0xe7, 0x20, 0x12, + 0x22, 0x8a, 0xb1, 0xa6, 0xdb, 0x61, 0xf6, 0x54, 0xc3, 0x71, 0xa2, 0x5e, 0x8d, 0xc8, 0x7d, 0xb3, + 0x60, 0x23, 0xd4, 0xde, 0x50, 0x0d, 0x54, 0x26, 0xe9, 0x19, 0x94, 0xa5, 0x3e, 0x55, 0xad, 0x63, + 0xeb, 0x64, 0xab, 0x7e, 0x64, 0x84, 0xd2, 0xfb, 0xaa, 0xf2, 0x4c, 0xb9, 0x12, 0x23, 0xe4, 0x33, + 0xb9, 0xfb, 0x00, 0xb0, 0x98, 0xd2, 0x4d, 0xb0, 0xfb, 0x81, 0xcf, 0xae, 0x6f, 0x03, 0xe6, 0x93, + 0x02, 0xad, 0xc0, 0x5a, 0xd8, 0x6b, 0xf0, 0x1e, 0xf3, 0x89, 0x65, 0x9a, 0x4e, 0xb7, 0xcb, 0x7c, + 0x52, 0xa4, 0x00, 0xe5, 0x6e, 0xa3, 0x1f, 0x32, 0x9f, 0xac, 0x50, 0x1b, 0x4a, 0x8c, 0xf3, 0x0e, + 0x27, 0xab, 0xb9, 0xa6, 0x1f, 0xb4, 0x82, 0xce, 0x7d, 0x40, 0x4a, 0x6e, 0x0b, 0xb6, 0xdb, 0x22, + 0x6a, 0xe3, 0x14, 0x63, 0x8e, 0x2f, 0x19, 0x4a, 0x45, 0x0f, 0xc1, 0x8e, 0x45, 0x74, 0x27, 0x46, + 0x59, 0x8c, 0xfa, 0xa6, 0x36, 0x5f, 0x0c, 0xa8, 0x03, 0xeb, 0xf1, 0xcc, 0x50, 0x2d, 0xea, 0xe5, + 0x67, 0xef, 0xb6, 0x81, 0x2c, 0xc2, 0x64, 0x22, 0x26, 0x12, 0x97, 0x4f, 0xab, 0xbf, 0x17, 0xa1, + 0xd4, 0xc8, 0xa1, 0xd3, 0x73, 0xb0, 0x9b, 0xa8, 0x66, 0x14, 0xf7, 0x3c, 0x03, 0xdd, 0x9b, 0x43, + 0xf7, 0x58, 0x0e, 0xdd, 0xd9, 0xfd, 0x8d, 0xa6, 0x5b, 0xa0, 0x97, 0x50, 0x09, 0xd5, 0x20, 0x55, + 0x66, 0xfc, 0x67, 0xfb, 0x45, 0xce, 0x5e, 0x24, 0x4b, 0xba, 0x6f, 0x60, 0xa7, 0x89, 0xca, 0x3c, + 0x76, 0x8e, 0x86, 0xee, 0xcf, 0xc5, 0xdf, 0xc8, 0x3b, 0xd5, 0x9f, 0x0b, 0x43, 0xd1, 0x24, 0x85, + 0xff, 0x92, 0x34, 0x34, 0x9f, 0xf7, 0xf4, 0x23, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x4b, 0xae, 0xec, + 0xd9, 0x02, 0x00, 0x00, } diff --git a/protos/server_admin.proto b/protos/server_admin.proto index ff86c9f5590..bc80a91293e 100644 --- a/protos/server_admin.proto +++ b/protos/server_admin.proto @@ -26,6 +26,8 @@ service Admin { rpc GetStatus(google.protobuf.Empty) returns (ServerStatus) {} rpc StartServer(google.protobuf.Empty) returns (ServerStatus) {} rpc StopServer(google.protobuf.Empty) returns (ServerStatus) {} + rpc GetModuleLogLevel(LogLevelRequest) returns (LogLevelResponse) {} + rpc SetModuleLogLevel(LogLevelRequest) returns (LogLevelResponse) {} } message ServerStatus { @@ -42,3 +44,12 @@ message ServerStatus { StatusCode status = 1; } +message LogLevelRequest { + string logModule = 1; + string logLevel = 2; +} + +message LogLevelResponse { + string logModule = 1; + string logLevel = 2; +}