2018-07-31 15:10:37 +01:00
|
|
|
// Copyright (C) 2018 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package logging
|
|
|
|
|
|
|
|
import (
|
|
|
|
context "context"
|
|
|
|
io "io"
|
2018-08-20 18:55:39 +01:00
|
|
|
"reflect"
|
2018-07-31 15:10:37 +01:00
|
|
|
"time"
|
|
|
|
|
|
|
|
minio "github.com/minio/minio/cmd"
|
|
|
|
"github.com/minio/minio/pkg/auth"
|
|
|
|
"github.com/minio/minio/pkg/hash"
|
|
|
|
"github.com/minio/minio/pkg/madmin"
|
|
|
|
"github.com/minio/minio/pkg/policy"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
)
|
|
|
|
|
2018-09-09 12:27:09 +01:00
|
|
|
const (
|
|
|
|
errTemplate = "gateway error: %v"
|
|
|
|
debugTemplate = "gateway error: %+v"
|
|
|
|
)
|
2018-07-31 15:10:37 +01:00
|
|
|
|
|
|
|
type gwLogWrap struct {
|
|
|
|
gw minio.Gateway
|
|
|
|
}
|
|
|
|
|
|
|
|
// Gateway is a wrapper of minio.Gateway that logs errors before
|
|
|
|
// returning them.
|
|
|
|
func Gateway(gw minio.Gateway) minio.Gateway {
|
|
|
|
return &gwLogWrap{gw: gw}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (lg *gwLogWrap) Name() string { return lg.gw.Name() }
|
|
|
|
func (lg *gwLogWrap) Production() bool { return lg.gw.Production() }
|
|
|
|
func (lg *gwLogWrap) NewGatewayLayer(creds auth.Credentials) (
|
|
|
|
minio.ObjectLayer, error) {
|
|
|
|
ol, err := lg.gw.NewGatewayLayer(creds)
|
|
|
|
return &olLogWrap{ol: ol, logger: zap.S()}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
type olLogWrap struct {
|
|
|
|
ol minio.ObjectLayer
|
|
|
|
logger ErrorLogger
|
|
|
|
}
|
|
|
|
|
2018-08-20 18:55:39 +01:00
|
|
|
// ErrorLogger logs a templated error message.
|
2018-07-31 15:10:37 +01:00
|
|
|
type ErrorLogger interface {
|
|
|
|
Errorf(template string, args ...interface{})
|
2018-09-09 12:27:09 +01:00
|
|
|
Debugf(template string, args ...interface{})
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
2018-08-20 18:55:39 +01:00
|
|
|
// minioError checks if the given error is a minio error.
|
|
|
|
func minioError(err error) bool {
|
|
|
|
return reflect.TypeOf(err).ConvertibleTo(reflect.TypeOf(minio.GenericError{}))
|
|
|
|
}
|
|
|
|
|
|
|
|
// log unexpected errors, i.e. non-minio errors. It will return the given error
|
|
|
|
// to allow method chaining.
|
|
|
|
func (ol *olLogWrap) log(err error) error {
|
|
|
|
if err != nil && !minioError(err) {
|
2018-07-31 15:10:37 +01:00
|
|
|
ol.logger.Errorf(errTemplate, err)
|
2018-09-09 12:27:09 +01:00
|
|
|
ol.logger.Debugf(debugTemplate, err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) Shutdown(ctx context.Context) error {
|
2018-08-20 18:55:39 +01:00
|
|
|
return ol.log(ol.ol.Shutdown(ctx))
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) StorageInfo(ctx context.Context) minio.StorageInfo {
|
|
|
|
return ol.ol.StorageInfo(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) MakeBucketWithLocation(ctx context.Context,
|
|
|
|
bucket string, location string) error {
|
2018-08-20 18:55:39 +01:00
|
|
|
return ol.log(ol.ol.MakeBucketWithLocation(ctx, bucket, location))
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) GetBucketInfo(ctx context.Context, bucket string) (
|
|
|
|
bucketInfo minio.BucketInfo, err error) {
|
|
|
|
bucketInfo, err = ol.ol.GetBucketInfo(ctx, bucket)
|
2018-08-20 18:55:39 +01:00
|
|
|
return bucketInfo, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) ListBuckets(ctx context.Context) (
|
|
|
|
buckets []minio.BucketInfo, err error) {
|
|
|
|
buckets, err = ol.ol.ListBuckets(ctx)
|
2018-08-20 18:55:39 +01:00
|
|
|
return buckets, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) DeleteBucket(ctx context.Context, bucket string) error {
|
2018-08-20 18:55:39 +01:00
|
|
|
return ol.log(ol.ol.DeleteBucket(ctx, bucket))
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) ListObjects(ctx context.Context,
|
|
|
|
bucket, prefix, marker, delimiter string, maxKeys int) (
|
|
|
|
result minio.ListObjectsInfo, err error) {
|
|
|
|
result, err = ol.ol.ListObjects(ctx, bucket, prefix, marker, delimiter,
|
|
|
|
maxKeys)
|
2018-08-20 18:55:39 +01:00
|
|
|
return result, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) ListObjectsV2(ctx context.Context,
|
|
|
|
bucket, prefix, continuationToken, delimiter string, maxKeys int,
|
|
|
|
fetchOwner bool, startAfter string) (result minio.ListObjectsV2Info,
|
|
|
|
err error) {
|
|
|
|
result, err = ol.ol.ListObjectsV2(ctx, bucket, prefix, continuationToken,
|
|
|
|
delimiter, maxKeys, fetchOwner, startAfter)
|
2018-08-20 18:55:39 +01:00
|
|
|
return result, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) GetObject(ctx context.Context, bucket, object string,
|
|
|
|
startOffset int64, length int64, writer io.Writer, etag string) (err error) {
|
2018-08-20 18:55:39 +01:00
|
|
|
return ol.log(ol.ol.GetObject(ctx, bucket, object, startOffset, length,
|
2018-07-31 15:10:37 +01:00
|
|
|
writer, etag))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) GetObjectInfo(ctx context.Context, bucket, object string) (
|
|
|
|
objInfo minio.ObjectInfo, err error) {
|
|
|
|
objInfo, err = ol.ol.GetObjectInfo(ctx, bucket, object)
|
2018-08-20 18:55:39 +01:00
|
|
|
return objInfo, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) PutObject(ctx context.Context, bucket, object string,
|
|
|
|
data *hash.Reader, metadata map[string]string) (objInfo minio.ObjectInfo,
|
|
|
|
err error) {
|
|
|
|
objInfo, err = ol.ol.PutObject(ctx, bucket, object, data, metadata)
|
2018-08-20 18:55:39 +01:00
|
|
|
return objInfo, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) CopyObject(ctx context.Context,
|
|
|
|
srcBucket, srcObject, destBucket, destObject string,
|
|
|
|
srcInfo minio.ObjectInfo) (objInfo minio.ObjectInfo, err error) {
|
|
|
|
objInfo, err = ol.ol.CopyObject(ctx, srcBucket, srcObject, destBucket,
|
|
|
|
destObject, srcInfo)
|
2018-08-20 18:55:39 +01:00
|
|
|
return objInfo, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) DeleteObject(ctx context.Context, bucket, object string) (
|
|
|
|
err error) {
|
2018-08-20 18:55:39 +01:00
|
|
|
return ol.log(ol.ol.DeleteObject(ctx, bucket, object))
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) ListMultipartUploads(ctx context.Context,
|
|
|
|
bucket, prefix, keyMarker, uploadIDMarker, delimiter string, maxUploads int) (
|
|
|
|
result minio.ListMultipartsInfo, err error) {
|
|
|
|
result, err = ol.ol.ListMultipartUploads(ctx, bucket, prefix, keyMarker,
|
|
|
|
uploadIDMarker, delimiter, maxUploads)
|
2018-08-20 18:55:39 +01:00
|
|
|
return result, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) NewMultipartUpload(ctx context.Context,
|
|
|
|
bucket, object string, metadata map[string]string) (uploadID string,
|
|
|
|
err error) {
|
|
|
|
uploadID, err = ol.ol.NewMultipartUpload(ctx, bucket, object, metadata)
|
2018-08-20 18:55:39 +01:00
|
|
|
return uploadID, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) CopyObjectPart(ctx context.Context,
|
|
|
|
srcBucket, srcObject, destBucket, destObject string, uploadID string,
|
|
|
|
partID int, startOffset int64, length int64, srcInfo minio.ObjectInfo) (
|
|
|
|
info minio.PartInfo, err error) {
|
|
|
|
info, err = ol.ol.CopyObjectPart(ctx, srcBucket, srcObject, destBucket,
|
|
|
|
destObject, uploadID, partID, startOffset, length, srcInfo)
|
2018-08-20 18:55:39 +01:00
|
|
|
return info, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) PutObjectPart(ctx context.Context,
|
|
|
|
bucket, object, uploadID string, partID int, data *hash.Reader) (
|
|
|
|
info minio.PartInfo, err error) {
|
|
|
|
info, err = ol.ol.PutObjectPart(ctx, bucket, object, uploadID, partID, data)
|
2018-08-20 18:55:39 +01:00
|
|
|
return info, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) ListObjectParts(ctx context.Context,
|
|
|
|
bucket, object, uploadID string, partNumberMarker int, maxParts int) (
|
|
|
|
result minio.ListPartsInfo, err error) {
|
|
|
|
result, err = ol.ol.ListObjectParts(ctx, bucket, object, uploadID,
|
|
|
|
partNumberMarker, maxParts)
|
2018-08-20 18:55:39 +01:00
|
|
|
return result, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) AbortMultipartUpload(ctx context.Context,
|
|
|
|
bucket, object, uploadID string) error {
|
2018-08-20 18:55:39 +01:00
|
|
|
return ol.log(ol.ol.AbortMultipartUpload(ctx, bucket, object, uploadID))
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) CompleteMultipartUpload(ctx context.Context,
|
|
|
|
bucket, object, uploadID string, uploadedParts []minio.CompletePart) (
|
|
|
|
objInfo minio.ObjectInfo, err error) {
|
|
|
|
objInfo, err = ol.ol.CompleteMultipartUpload(ctx, bucket, object, uploadID,
|
|
|
|
uploadedParts)
|
2018-08-20 18:55:39 +01:00
|
|
|
return objInfo, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) ReloadFormat(ctx context.Context, dryRun bool) error {
|
2018-08-20 18:55:39 +01:00
|
|
|
return ol.log(ol.ol.ReloadFormat(ctx, dryRun))
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) HealFormat(ctx context.Context, dryRun bool) (
|
|
|
|
madmin.HealResultItem, error) {
|
|
|
|
rv, err := ol.ol.HealFormat(ctx, dryRun)
|
2018-08-20 18:55:39 +01:00
|
|
|
return rv, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) HealBucket(ctx context.Context, bucket string,
|
|
|
|
dryRun bool) ([]madmin.HealResultItem, error) {
|
|
|
|
rv, err := ol.ol.HealBucket(ctx, bucket, dryRun)
|
2018-08-20 18:55:39 +01:00
|
|
|
return rv, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) HealObject(ctx context.Context, bucket, object string,
|
|
|
|
dryRun bool) (madmin.HealResultItem, error) {
|
|
|
|
rv, err := ol.ol.HealObject(ctx, bucket, object, dryRun)
|
2018-08-20 18:55:39 +01:00
|
|
|
return rv, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) ListBucketsHeal(ctx context.Context) (
|
|
|
|
buckets []minio.BucketInfo, err error) {
|
|
|
|
buckets, err = ol.ol.ListBucketsHeal(ctx)
|
2018-08-20 18:55:39 +01:00
|
|
|
return buckets, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) ListObjectsHeal(ctx context.Context,
|
|
|
|
bucket, prefix, marker, delimiter string, maxKeys int) (
|
|
|
|
minio.ListObjectsInfo, error) {
|
|
|
|
rv, err := ol.ol.ListObjectsHeal(ctx, bucket, prefix, marker, delimiter,
|
|
|
|
maxKeys)
|
2018-08-20 18:55:39 +01:00
|
|
|
return rv, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) ListLocks(ctx context.Context, bucket, prefix string,
|
|
|
|
duration time.Duration) ([]minio.VolumeLockInfo, error) {
|
|
|
|
rv, err := ol.ol.ListLocks(ctx, bucket, prefix, duration)
|
2018-08-20 18:55:39 +01:00
|
|
|
return rv, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) ClearLocks(ctx context.Context,
|
|
|
|
lockInfos []minio.VolumeLockInfo) error {
|
2018-08-20 18:55:39 +01:00
|
|
|
return ol.log(ol.ol.ClearLocks(ctx, lockInfos))
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) SetBucketPolicy(ctx context.Context, n string,
|
|
|
|
p *policy.Policy) error {
|
2018-08-20 18:55:39 +01:00
|
|
|
return ol.log(ol.ol.SetBucketPolicy(ctx, n, p))
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) GetBucketPolicy(ctx context.Context, n string) (
|
|
|
|
*policy.Policy, error) {
|
|
|
|
p, err := ol.ol.GetBucketPolicy(ctx, n)
|
2018-08-20 18:55:39 +01:00
|
|
|
return p, ol.log(err)
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) DeleteBucketPolicy(ctx context.Context, n string) error {
|
2018-08-20 18:55:39 +01:00
|
|
|
return ol.log(ol.ol.DeleteBucketPolicy(ctx, n))
|
2018-07-31 15:10:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) IsNotificationSupported() bool {
|
|
|
|
return ol.ol.IsNotificationSupported()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ol *olLogWrap) IsEncryptionSupported() bool {
|
|
|
|
return ol.ol.IsEncryptionSupported()
|
|
|
|
}
|