Skip to content

Coding Convention

Jack Lin edited this page Apr 12, 2024 · 8 revisions

Logging

Reduce the number of logs

  • Prevent repeated logs happening in the resync reconciling loop or monitors
  • When doing an operation, log before with .Info("Ving + ...") and no need to log after the operation is successful since if there is any error, it will be returned and reported in the caller function.
  • If an error will be returned/bubbled up, no need to log the error but just enrich the error message with an error wrapper and return it for the upper function to handle and log the error.

Wording

  • For log messages:
    • Try to start with a capitalized verb in the continuous present or past tense (V+ing, V+ed).
    • Try to keep the message to one sentence with no final punctuation.
    • If there is an error, wrap it in the logger instead of using string interpolation in the message directly.
  • For errors to return, try to start with a lowercase verb in the continuous present or past tense (v+ing, v+ed).

Level convention

Longhorn by default use Info for the logging level, since we rely on users' support bundles to help debug the issue. We tend to minimize the number of Debug messages since they will not be shown in the support bundles by default.

  • Info: Used to track the change of states or the start of operations. These messages can help us to observe behaviors or debug issues.
  • Warn: Used for errors or abnormal behaviors which have been handled and won't affect and break this reconcile loop.
  • Error: Used for errors not being handled and will break this reconcile loop. Should be only used in the top caller function that catches the error.

Organize Package Imports

  • Package Import Order: Organize your package imports into three distinct groups, separated by a blank line:

    • Standard library packages
    • Third-party packages
    • Local packages
    • examples:
      	import (
      		// golang standard library packages such as "fmt", "path/filepath" and so on.
      		"context"
      		"fmt"
      		"path/filepath"
      		"strconv"
      
      		// third-party packages not related to k8s
      		"github.com/pkg/errors"
      		"github.com/sirupsen/logrus"
      		"go.uber.org/multierr"
      
      		// third-party packages without alias names related to k8s
      		corev1 "k8s.io/api/core/v1"
      
      		// third-party packages with alias names related to k8s
      		"k8s.io/kubernetes/pkg/controller"
      
      		// packages without alias names from longhorn components except for this repo 
      
      		// packages with alias names from longhorn components except for this repo 
      		imapi "github.com/longhorn/longhorn-instance-manager/pkg/api"
      		imclient "github.com/longhorn/longhorn-instance-manager/pkg/client"
      		immeta "github.com/longhorn/longhorn-instance-manager/pkg/meta"
      		imutil "github.com/longhorn/longhorn-instance-manager/pkg/util"
      		lhutils "github.com/longhorn/go-common-libs/utils"
      
      		// packages without alias names from this repo
      		"github.com/longhorn/longhorn-manager/datastore"
      		"github.com/longhorn/longhorn-manager/types"
      
      		// packages with alias names from this repo
      		longhorn "github.com/longhorn/longhorn-manager/k8s/pkg/apis/longhorn/v1beta2"
      	)
      
  • Group Packages Thematically: See example

  • Group Aliased Packages: If you alias any packages, import them immediately after the original package import and separate them with a blank line. See example.

  • Maintain Consistency: Check the project codebase to identify the package import pattern.

Functions

  • Descriptive and Clear Naming: Choose function names that accurately depict their purpose and functionality.
  • Start with Action Verbs: Begin function names with action verbs that describe what the function accomplishes. For instance:
    • Use createTempDirectory instead of tempDirectory for a function responsible for creating a temporary directory.
    • Use validateVolume instead of volumeValidation for a function tasked with validating a volume.
  • Avoid Ambiguity and Abbreviations: Ensure function names are unambiguous and do not rely on cryptic abbreviations. Opt for names that are self-explanatory and easy to comprehend. For example, prefer getBackupData over getBD.

Comments

Comments should be included for all exported entities, such as functions, methods, interfaces, structures, variables, constants, enums, etc.

Clone this wiki locally