forked from TrueCloudLab/restic
Print number of bytes added to the repo
This includes optional compression and crypto overhead.
This commit is contained in:
parent
99634c0936
commit
6c4ceaf1e7
6 changed files with 65 additions and 44 deletions
|
@ -31,18 +31,22 @@ type ErrorFunc func(file string, fi os.FileInfo, err error) error
|
||||||
|
|
||||||
// ItemStats collects some statistics about a particular file or directory.
|
// ItemStats collects some statistics about a particular file or directory.
|
||||||
type ItemStats struct {
|
type ItemStats struct {
|
||||||
DataBlobs int // number of new data blobs added for this item
|
DataBlobs int // number of new data blobs added for this item
|
||||||
DataSize uint64 // sum of the sizes of all new data blobs
|
DataSize uint64 // sum of the sizes of all new data blobs
|
||||||
TreeBlobs int // number of new tree blobs added for this item
|
DataSizeInRepo uint64 // sum of the bytes added to the repo (including compression and crypto overhead)
|
||||||
TreeSize uint64 // sum of the sizes of all new tree blobs
|
TreeBlobs int // number of new tree blobs added for this item
|
||||||
|
TreeSize uint64 // sum of the sizes of all new tree blobs
|
||||||
|
TreeSizeInRepo uint64 // sum of the bytes added to the repo (including compression and crypto overhead)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add adds other to the current ItemStats.
|
// Add adds other to the current ItemStats.
|
||||||
func (s *ItemStats) Add(other ItemStats) {
|
func (s *ItemStats) Add(other ItemStats) {
|
||||||
s.DataBlobs += other.DataBlobs
|
s.DataBlobs += other.DataBlobs
|
||||||
s.DataSize += other.DataSize
|
s.DataSize += other.DataSize
|
||||||
|
s.DataSizeInRepo += other.DataSizeInRepo
|
||||||
s.TreeBlobs += other.TreeBlobs
|
s.TreeBlobs += other.TreeBlobs
|
||||||
s.TreeSize += other.TreeSize
|
s.TreeSize += other.TreeSize
|
||||||
|
s.TreeSizeInRepo += other.TreeSizeInRepo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Archiver saves a directory structure to the repo.
|
// Archiver saves a directory structure to the repo.
|
||||||
|
@ -183,7 +187,8 @@ func (arch *Archiver) saveTree(ctx context.Context, t *restic.Tree) (restic.ID,
|
||||||
res.Wait(ctx)
|
res.Wait(ctx)
|
||||||
if !res.Known() {
|
if !res.Known() {
|
||||||
s.TreeBlobs++
|
s.TreeBlobs++
|
||||||
s.TreeSize += uint64(len(buf))
|
s.TreeSize += uint64(res.Length())
|
||||||
|
s.TreeSizeInRepo += uint64(res.SizeInRepo())
|
||||||
}
|
}
|
||||||
// The context was canceled in the meantime, res.ID() might be invalid
|
// The context was canceled in the meantime, res.ID() might be invalid
|
||||||
if ctx.Err() != nil {
|
if ctx.Err() != nil {
|
||||||
|
|
|
@ -1019,7 +1019,7 @@ func TestArchiverSaveTree(t *testing.T) {
|
||||||
want: TestDir{
|
want: TestDir{
|
||||||
"targetfile": TestFile{Content: string("foobar")},
|
"targetfile": TestFile{Content: string("foobar")},
|
||||||
},
|
},
|
||||||
stat: ItemStats{1, 6, 0, 0},
|
stat: ItemStats{1, 6, 32 + 6, 0, 0, 0},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
src: TestDir{
|
src: TestDir{
|
||||||
|
@ -1031,7 +1031,7 @@ func TestArchiverSaveTree(t *testing.T) {
|
||||||
"targetfile": TestFile{Content: string("foobar")},
|
"targetfile": TestFile{Content: string("foobar")},
|
||||||
"filesymlink": TestSymlink{Target: "targetfile"},
|
"filesymlink": TestSymlink{Target: "targetfile"},
|
||||||
},
|
},
|
||||||
stat: ItemStats{1, 6, 0, 0},
|
stat: ItemStats{1, 6, 32 + 6, 0, 0, 0},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
src: TestDir{
|
src: TestDir{
|
||||||
|
@ -1051,7 +1051,7 @@ func TestArchiverSaveTree(t *testing.T) {
|
||||||
"symlink": TestSymlink{Target: "subdir"},
|
"symlink": TestSymlink{Target: "subdir"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
stat: ItemStats{0, 0, 1, 0x154},
|
stat: ItemStats{0, 0, 0, 1, 0x154, 0x16a},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
src: TestDir{
|
src: TestDir{
|
||||||
|
@ -1075,7 +1075,7 @@ func TestArchiverSaveTree(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
stat: ItemStats{1, 6, 3, 0x47f},
|
stat: ItemStats{1, 6, 32 + 6, 3, 0x47f, 0x4c1},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1140,7 +1140,8 @@ func TestArchiverSaveTree(t *testing.T) {
|
||||||
bothZeroOrNeither(t, uint64(test.stat.DataBlobs), uint64(stat.DataBlobs))
|
bothZeroOrNeither(t, uint64(test.stat.DataBlobs), uint64(stat.DataBlobs))
|
||||||
bothZeroOrNeither(t, uint64(test.stat.TreeBlobs), uint64(stat.TreeBlobs))
|
bothZeroOrNeither(t, uint64(test.stat.TreeBlobs), uint64(stat.TreeBlobs))
|
||||||
bothZeroOrNeither(t, test.stat.DataSize, stat.DataSize)
|
bothZeroOrNeither(t, test.stat.DataSize, stat.DataSize)
|
||||||
bothZeroOrNeither(t, test.stat.TreeSize, stat.TreeSize)
|
bothZeroOrNeither(t, test.stat.DataSizeInRepo, stat.DataSizeInRepo)
|
||||||
|
bothZeroOrNeither(t, test.stat.TreeSizeInRepo, stat.TreeSizeInRepo)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,11 +86,17 @@ func (s *FutureBlob) Known() bool {
|
||||||
return s.res.known
|
return s.res.known
|
||||||
}
|
}
|
||||||
|
|
||||||
// Length returns the length of the blob.
|
// Length returns the raw length of the blob.
|
||||||
func (s *FutureBlob) Length() int {
|
func (s *FutureBlob) Length() int {
|
||||||
return s.length
|
return s.length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SizeInRepo returns the number of bytes added to the repo (including
|
||||||
|
// compression and crypto overhead).
|
||||||
|
func (s *FutureBlob) SizeInRepo() int {
|
||||||
|
return s.res.size
|
||||||
|
}
|
||||||
|
|
||||||
type saveBlobJob struct {
|
type saveBlobJob struct {
|
||||||
restic.BlobType
|
restic.BlobType
|
||||||
buf *Buffer
|
buf *Buffer
|
||||||
|
|
|
@ -210,6 +210,7 @@ func (s *FileSaver) saveFile(ctx context.Context, chnker *chunker.Chunker, snPat
|
||||||
if !res.Known() {
|
if !res.Known() {
|
||||||
stats.DataBlobs++
|
stats.DataBlobs++
|
||||||
stats.DataSize += uint64(res.Length())
|
stats.DataSize += uint64(res.Length())
|
||||||
|
stats.DataSizeInRepo += uint64(res.SizeInRepo())
|
||||||
}
|
}
|
||||||
|
|
||||||
node.Content = append(node.Content, res.ID())
|
node.Content = append(node.Content, res.ID())
|
||||||
|
|
|
@ -110,12 +110,14 @@ func (b *JSONProgress) CompleteItem(messageType, item string, previous, current
|
||||||
switch messageType {
|
switch messageType {
|
||||||
case "dir new":
|
case "dir new":
|
||||||
b.print(verboseUpdate{
|
b.print(verboseUpdate{
|
||||||
MessageType: "verbose_status",
|
MessageType: "verbose_status",
|
||||||
Action: "new",
|
Action: "new",
|
||||||
Item: item,
|
Item: item,
|
||||||
Duration: d.Seconds(),
|
Duration: d.Seconds(),
|
||||||
DataSize: s.DataSize,
|
DataSize: s.DataSize,
|
||||||
MetadataSize: s.TreeSize,
|
DataSizeInRepo: s.DataSizeInRepo,
|
||||||
|
MetadataSize: s.TreeSize,
|
||||||
|
MetadataSizeInRepo: s.TreeSizeInRepo,
|
||||||
})
|
})
|
||||||
case "dir unchanged":
|
case "dir unchanged":
|
||||||
b.print(verboseUpdate{
|
b.print(verboseUpdate{
|
||||||
|
@ -125,20 +127,23 @@ func (b *JSONProgress) CompleteItem(messageType, item string, previous, current
|
||||||
})
|
})
|
||||||
case "dir modified":
|
case "dir modified":
|
||||||
b.print(verboseUpdate{
|
b.print(verboseUpdate{
|
||||||
MessageType: "verbose_status",
|
MessageType: "verbose_status",
|
||||||
Action: "modified",
|
Action: "modified",
|
||||||
Item: item,
|
Item: item,
|
||||||
Duration: d.Seconds(),
|
Duration: d.Seconds(),
|
||||||
DataSize: s.DataSize,
|
DataSize: s.DataSize,
|
||||||
MetadataSize: s.TreeSize,
|
DataSizeInRepo: s.DataSizeInRepo,
|
||||||
|
MetadataSize: s.TreeSize,
|
||||||
|
MetadataSizeInRepo: s.TreeSizeInRepo,
|
||||||
})
|
})
|
||||||
case "file new":
|
case "file new":
|
||||||
b.print(verboseUpdate{
|
b.print(verboseUpdate{
|
||||||
MessageType: "verbose_status",
|
MessageType: "verbose_status",
|
||||||
Action: "new",
|
Action: "new",
|
||||||
Item: item,
|
Item: item,
|
||||||
Duration: d.Seconds(),
|
Duration: d.Seconds(),
|
||||||
DataSize: s.DataSize,
|
DataSize: s.DataSize,
|
||||||
|
DataSizeInRepo: s.DataSizeInRepo,
|
||||||
})
|
})
|
||||||
case "file unchanged":
|
case "file unchanged":
|
||||||
b.print(verboseUpdate{
|
b.print(verboseUpdate{
|
||||||
|
@ -148,11 +153,12 @@ func (b *JSONProgress) CompleteItem(messageType, item string, previous, current
|
||||||
})
|
})
|
||||||
case "file modified":
|
case "file modified":
|
||||||
b.print(verboseUpdate{
|
b.print(verboseUpdate{
|
||||||
MessageType: "verbose_status",
|
MessageType: "verbose_status",
|
||||||
Action: "modified",
|
Action: "modified",
|
||||||
Item: item,
|
Item: item,
|
||||||
Duration: d.Seconds(),
|
Duration: d.Seconds(),
|
||||||
DataSize: s.DataSize,
|
DataSize: s.DataSize,
|
||||||
|
DataSizeInRepo: s.DataSizeInRepo,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,13 +222,15 @@ type errorUpdate struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type verboseUpdate struct {
|
type verboseUpdate struct {
|
||||||
MessageType string `json:"message_type"` // "verbose_status"
|
MessageType string `json:"message_type"` // "verbose_status"
|
||||||
Action string `json:"action"`
|
Action string `json:"action"`
|
||||||
Item string `json:"item"`
|
Item string `json:"item"`
|
||||||
Duration float64 `json:"duration"` // in seconds
|
Duration float64 `json:"duration"` // in seconds
|
||||||
DataSize uint64 `json:"data_size"`
|
DataSize uint64 `json:"data_size"`
|
||||||
MetadataSize uint64 `json:"metadata_size"`
|
DataSizeInRepo uint64 `json:"data_size_in_repo"`
|
||||||
TotalFiles uint `json:"total_files"`
|
MetadataSize uint64 `json:"metadata_size"`
|
||||||
|
MetadataSizeInRepo uint64 `json:"metadata_size_in_repo"`
|
||||||
|
TotalFiles uint `json:"total_files"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type summaryOutput struct {
|
type summaryOutput struct {
|
||||||
|
|
|
@ -138,17 +138,17 @@ func formatBytes(c uint64) string {
|
||||||
func (b *TextProgress) CompleteItem(messageType, item string, previous, current *restic.Node, s archiver.ItemStats, d time.Duration) {
|
func (b *TextProgress) CompleteItem(messageType, item string, previous, current *restic.Node, s archiver.ItemStats, d time.Duration) {
|
||||||
switch messageType {
|
switch messageType {
|
||||||
case "dir new":
|
case "dir new":
|
||||||
b.VV("new %v, saved in %.3fs (%v added, %v metadata)", item, d.Seconds(), formatBytes(s.DataSize), formatBytes(s.TreeSize))
|
b.VV("new %v, saved in %.3fs (%v added, %v stored, %v metadata)", item, d.Seconds(), formatBytes(s.DataSize), formatBytes(s.DataSizeInRepo), formatBytes(s.TreeSizeInRepo))
|
||||||
case "dir unchanged":
|
case "dir unchanged":
|
||||||
b.VV("unchanged %v", item)
|
b.VV("unchanged %v", item)
|
||||||
case "dir modified":
|
case "dir modified":
|
||||||
b.VV("modified %v, saved in %.3fs (%v added, %v metadata)", item, d.Seconds(), formatBytes(s.DataSize), formatBytes(s.TreeSize))
|
b.VV("modified %v, saved in %.3fs (%v added, %v stored, %v metadata)", item, d.Seconds(), formatBytes(s.DataSize), formatBytes(s.DataSizeInRepo), formatBytes(s.TreeSizeInRepo))
|
||||||
case "file new":
|
case "file new":
|
||||||
b.VV("new %v, saved in %.3fs (%v added)", item, d.Seconds(), formatBytes(s.DataSize))
|
b.VV("new %v, saved in %.3fs (%v added)", item, d.Seconds(), formatBytes(s.DataSize))
|
||||||
case "file unchanged":
|
case "file unchanged":
|
||||||
b.VV("unchanged %v", item)
|
b.VV("unchanged %v", item)
|
||||||
case "file modified":
|
case "file modified":
|
||||||
b.VV("modified %v, saved in %.3fs (%v added)", item, d.Seconds(), formatBytes(s.DataSize))
|
b.VV("modified %v, saved in %.3fs (%v added, %v stored)", item, d.Seconds(), formatBytes(s.DataSize), formatBytes(s.DataSizeInRepo))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ func (b *TextProgress) Finish(snapshotID restic.ID, start time.Time, summary *Su
|
||||||
if dryRun {
|
if dryRun {
|
||||||
verb = "Would add"
|
verb = "Would add"
|
||||||
}
|
}
|
||||||
b.P("%s to the repo: %-5s\n", verb, formatBytes(summary.ItemStats.DataSize+summary.ItemStats.TreeSize))
|
b.P("%s to the repo: %-5s (%-5s stored)\n", verb, formatBytes(summary.ItemStats.DataSize+summary.ItemStats.TreeSize), formatBytes(summary.ItemStats.DataSizeInRepo+summary.ItemStats.TreeSizeInRepo))
|
||||||
b.P("\n")
|
b.P("\n")
|
||||||
b.P("processed %v files, %v in %s",
|
b.P("processed %v files, %v in %s",
|
||||||
summary.Files.New+summary.Files.Changed+summary.Files.Unchanged,
|
summary.Files.New+summary.Files.Changed+summary.Files.Unchanged,
|
||||||
|
|
Loading…
Reference in a new issue