diff --git a/internal/pkg/commands/loglevel.go b/internal/pkg/commands/loglevel.go
new file mode 100644
index 0000000..265ab8f
--- /dev/null
+++ b/internal/pkg/commands/loglevel.go
@@ -0,0 +1,446 @@
+/*
+ * Copyright 2019-present Ciena Corporation
+ *
+ * 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 commands
+
+import (
+	"context"
+	"fmt"
+	"github.com/fullstorydev/grpcurl"
+	flags "github.com/jessevdk/go-flags"
+	"github.com/jhump/protoreflect/dynamic"
+	"github.com/opencord/voltctl/pkg/format"
+	"github.com/opencord/voltctl/pkg/model"
+	"google.golang.org/grpc"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/tools/clientcmd"
+	"log"
+	"strings"
+)
+
+type SetLogLevelOutput struct {
+	ComponentName string
+	Status        string
+	Error         string
+}
+
+type SetLogLevelOpts struct {
+	OutputOptions
+	Package string `short:"p" long:"package" description:"Package name to set filter level"`
+	Args    struct {
+		Level     string
+		Component []string
+	} `positional-args:"yes" required:"yes"`
+}
+
+type GetLogLevelsOpts struct {
+	ListOutputOptions
+	Args struct {
+		Component []string
+	} `positional-args:"yes" required:"yes"`
+}
+
+type ListLogLevelsOpts struct {
+	ListOutputOptions
+}
+
+type LogLevelOpts struct {
+	SetLogLevel   SetLogLevelOpts   `command:"set"`
+	GetLogLevels  GetLogLevelsOpts  `command:"get"`
+	ListLogLevels ListLogLevelsOpts `command:"list"`
+}
+
+var logLevelOpts = LogLevelOpts{}
+
+const (
+	DEFAULT_LOGLEVELS_FORMAT   = "table{{ .ComponentName }}\t{{.PackageName}}\t{{.Level}}"
+	DEFAULT_SETLOGLEVEL_FORMAT = "table{{ .ComponentName }}\t{{.Status}}\t{{.Error}}"
+)
+
+func RegisterLogLevelCommands(parent *flags.Parser) {
+	_, err := parent.AddCommand("loglevel", "loglevel commands", "Get and set log levels", &logLevelOpts)
+	if err != nil {
+		panic(err)
+	}
+}
+
+func MapListAppend(m map[string][]string, name string, item string) {
+	list, okay := m[name]
+	if okay {
+		m[name] = append(list, item)
+	} else {
+		m[name] = []string{item}
+	}
+}
+
+/*
+ * A roundabout way of going of using the LogLevel enum to map from
+ * a string to an integer that we can pass into the dynamic
+ * proto.
+ *
+ * TODO: There's probably an easier way.
+ */
+func LogLevelStringToInt(logLevelString string) (int32, error) {
+	ProcessGlobalOptions() // required for GetMethod()
+
+	/*
+	 * Use GetMethod() to get us a descriptor on the proto file we're
+	 * interested in.
+	 */
+
+	descriptor, _, err := GetMethod("update-log-level")
+	if err != nil {
+		return 0, err
+	}
+
+	/*
+	 * Map string LogLevel to enumerated type LogLevel
+	 * We have descriptor from above, which is a DescriptorSource
+	 * We can use FindSymbol to get at the message
+	 */
+
+	loggingSymbol, err := descriptor.FindSymbol("common.LogLevel")
+	if err != nil {
+		return 0, err
+	}
+
+	/*
+	 * LoggingSymbol is a Descriptor, but not a MessageDescrptior,
+	 * so we can't look at it's fields yet. Go back to the file,
+	 * call FindMessage to get the Message, then we can get the
+	 * embedded enum.
+	 */
+
+	loggingFile := loggingSymbol.GetFile()
+	logLevelMessage := loggingFile.FindMessage("common.LogLevel")
+	logLevelEnumType := logLevelMessage.GetNestedEnumTypes()[0]
+	enumLogLevel := logLevelEnumType.FindValueByName(logLevelString)
+
+	if enumLogLevel == nil {
+		return 0, fmt.Errorf("Unknown log level %s", logLevelString)
+	}
+
+	return enumLogLevel.GetNumber(), nil
+}
+
+// Validate a list of component names and throw an error if any one of them is bad.
+func ValidateComponentNames(kube_to_arouter map[string][]string, names []string) error {
+	var badNames []string
+	for _, name := range names {
+		_, ok := kube_to_arouter[name]
+		if !ok {
+			badNames = append(badNames, name)
+		}
+	}
+
+	if len(badNames) > 0 {
+		return fmt.Errorf("Unknown components: %s", strings.Join(badNames, ","))
+	} else {
+		return nil
+	}
+}
+
+func BuildKubernetesNameMap() (map[string][]string, map[string]string, error) {
+	kube_to_arouter := make(map[string][]string)
+	arouter_to_kube := make(map[string]string)
+
+	// use the current context in kubeconfig
+	config, err := clientcmd.BuildConfigFromFlags("", GlobalOptions.K8sConfig)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// create the clientset
+	clientset, err := kubernetes.NewForConfig(config)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	pods, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{
+		LabelSelector: "app.kubernetes.io/part-of=voltha",
+	})
+	if err != nil {
+		return nil, nil, err
+	}
+
+	if len(pods.Items) == 0 {
+		return nil, nil, fmt.Errorf("No Voltha pods found in Kubernetes -- verify pod is setup")
+	}
+
+	for _, pod := range pods.Items {
+		app, ok := pod.Labels["app"]
+		if !ok {
+			continue
+		}
+
+		var arouter_name string
+
+		switch app {
+		case "voltha-api-server":
+			/*
+			 * Assumes a single api_server for now.
+			 * TODO: Make labeling changes in charts to be able to derive name from labels
+			 */
+			arouter_name = "api_server0.api_server01"
+		case "rw-core":
+			affinity_group, ok := pod.Labels["affinity-group"]
+			if !ok {
+				log.Printf("rwcore %s lacks affinity-group label", pod.Name)
+				continue
+			}
+			affinity_group_core_id, ok := pod.Labels["affinity-group-core-id"]
+			if !ok {
+				log.Printf("rwcore %s lacks affinity-group-core-id label", pod.Name)
+				continue
+			}
+			arouter_name = "vcore" + affinity_group + ".vcore" + affinity_group + affinity_group_core_id
+		case "ro-core":
+			/*
+			 * Assumes a single rocore for now.
+			 * TODO: Make labeling changes in charts to be able to derive name from labels
+			 */
+			arouter_name = "ro_vcore0.ro_vcore01"
+		default:
+			// skip this pod as it's not relevant
+			continue
+		}
+
+		// Multiple ways to identify the component
+
+		// 1) The pod name. One pod name maps to exactly one pod.
+
+		arouter_to_kube[arouter_name] = pod.Name
+		MapListAppend(kube_to_arouter, pod.Name, arouter_name)
+
+		// 2) The kubernetes component name. A single component (i.e. "core") may map to multiple pods.
+
+		component, ok := pod.Labels["app.kubernetes.io/component"]
+		if ok {
+			MapListAppend(kube_to_arouter, component, arouter_name)
+		}
+
+		// 3) The voltha app label. A single app (i.e. "rwcore") may map to multiple pods.
+
+		MapListAppend(kube_to_arouter, app, arouter_name)
+
+	}
+
+	return kube_to_arouter, arouter_to_kube, nil
+}
+
+func (options *SetLogLevelOpts) Execute(args []string) error {
+	if len(options.Args.Component) == 0 {
+		return fmt.Errorf("Please specify at least one component")
+	}
+
+	kube_to_arouter, arouter_to_kube, err := BuildKubernetesNameMap()
+	if err != nil {
+		return err
+	}
+
+	var output []SetLogLevelOutput
+
+	// Validate component names, throw error now to avoid doing partial work
+	err = ValidateComponentNames(kube_to_arouter, options.Args.Component)
+	if err != nil {
+		return err
+	}
+
+	// Validate and map the logLevel string to an integer, throw error now to avoid doing partial work
+	intLogLevel, err := LogLevelStringToInt(options.Args.Level)
+	if err != nil {
+		return err
+	}
+
+	for _, kubeComponentName := range options.Args.Component {
+		var descriptor grpcurl.DescriptorSource
+		var conn *grpc.ClientConn
+		var method string
+
+		componentNameList := kube_to_arouter[kubeComponentName]
+
+		for _, componentName := range componentNameList {
+			conn, err = NewConnection()
+			if err != nil {
+				return err
+			}
+			defer conn.Close()
+			if strings.HasPrefix(componentName, "api_server") {
+				// apiserver's UpdateLogLevel is in the afrouter.Configuration gRPC package
+				descriptor, method, err = GetMethod("apiserver-update-log-level")
+			} else {
+				descriptor, method, err = GetMethod("update-log-level")
+			}
+			if err != nil {
+				return err
+			}
+
+			ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
+			defer cancel()
+
+			ll := make(map[string]interface{})
+			ll["component_name"] = componentName
+			ll["package_name"] = options.Package
+			ll["level"] = intLogLevel
+
+			h := &RpcEventHandler{
+				Fields: map[string]map[string]interface{}{"common.Logging": ll},
+			}
+			err = grpcurl.InvokeRPC(ctx, descriptor, conn, method, []string{}, h, h.GetParams)
+			if err != nil {
+				return err
+			}
+
+			if h.Status != nil && h.Status.Err() != nil {
+				output = append(output, SetLogLevelOutput{ComponentName: arouter_to_kube[componentName], Status: "Failure", Error: h.Status.Err().Error()})
+				continue
+			}
+
+			output = append(output, SetLogLevelOutput{ComponentName: arouter_to_kube[componentName], Status: "Success"})
+		}
+	}
+
+	outputFormat := CharReplacer.Replace(options.Format)
+	if outputFormat == "" {
+		outputFormat = DEFAULT_SETLOGLEVEL_FORMAT
+	}
+
+	result := CommandResult{
+		Format:    format.Format(outputFormat),
+		OutputAs:  toOutputType(options.OutputAs),
+		NameLimit: options.NameLimit,
+		Data:      output,
+	}
+
+	GenerateOutput(&result)
+	return nil
+}
+
+func (options *GetLogLevelsOpts) Execute(args []string) error {
+	if len(options.Args.Component) == 0 {
+		return fmt.Errorf("Please specify at least one component")
+	}
+
+	kube_to_arouter, arouter_to_kube, err := BuildKubernetesNameMap()
+	if err != nil {
+		return err
+	}
+
+	var data []model.LogLevel
+
+	// Validate component names, throw error now to avoid doing partial work
+	err = ValidateComponentNames(kube_to_arouter, options.Args.Component)
+	if err != nil {
+		return err
+	}
+
+	for _, kubeComponentName := range options.Args.Component {
+		var descriptor grpcurl.DescriptorSource
+		var conn *grpc.ClientConn
+		var method string
+
+		componentNameList := kube_to_arouter[kubeComponentName]
+
+		for _, componentName := range componentNameList {
+			conn, err = NewConnection()
+			if err != nil {
+				return err
+			}
+			defer conn.Close()
+			if strings.HasPrefix(componentName, "api_server") {
+				// apiserver's UpdateLogLevel is in the afrouter.Configuration gRPC package
+				descriptor, method, err = GetMethod("apiserver-get-log-levels")
+			} else {
+				descriptor, method, err = GetMethod("get-log-levels")
+			}
+			if err != nil {
+				return err
+			}
+
+			ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
+			defer cancel()
+
+			ll := make(map[string]interface{})
+			ll["component_name"] = componentName
+
+			h := &RpcEventHandler{
+				Fields: map[string]map[string]interface{}{"common.LoggingComponent": ll},
+			}
+			err = grpcurl.InvokeRPC(ctx, descriptor, conn, method, []string{}, h, h.GetParams)
+			if err != nil {
+				return err
+			}
+
+			if h.Status != nil && h.Status.Err() != nil {
+				return h.Status.Err()
+			}
+
+			d, err := dynamic.AsDynamicMessage(h.Response)
+			if err != nil {
+				return err
+			}
+			items, err := d.TryGetFieldByName("items")
+			if err != nil {
+				return err
+			}
+
+			for _, item := range items.([]interface{}) {
+				logLevel := model.LogLevel{}
+				logLevel.PopulateFrom(item.(*dynamic.Message))
+				logLevel.ComponentName = arouter_to_kube[logLevel.ComponentName]
+
+				data = append(data, logLevel)
+			}
+		}
+	}
+
+	outputFormat := CharReplacer.Replace(options.Format)
+	if outputFormat == "" {
+		outputFormat = DEFAULT_LOGLEVELS_FORMAT
+	}
+
+	result := CommandResult{
+		Format:    format.Format(outputFormat),
+		Filter:    options.Filter,
+		OrderBy:   options.OrderBy,
+		OutputAs:  toOutputType(options.OutputAs),
+		NameLimit: options.NameLimit,
+		Data:      data,
+	}
+	GenerateOutput(&result)
+	return nil
+}
+
+func (options *ListLogLevelsOpts) Execute(args []string) error {
+	var getOptions GetLogLevelsOpts
+	var podNames []string
+
+	_, arouter_to_kube, err := BuildKubernetesNameMap()
+	if err != nil {
+		return err
+	}
+
+	for _, podName := range arouter_to_kube {
+		podNames = append(podNames, podName)
+	}
+
+	// Just call GetLogLevels with a list of podnames that includes everything relevant.
+
+	getOptions.ListOutputOptions = options.ListOutputOptions
+	getOptions.Args.Component = podNames
+
+	return getOptions.Execute(args)
+}
