|
|
|
@ -1,26 +1,42 @@ |
|
|
|
|
package statistics |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"encoding/json" |
|
|
|
|
"github.com/alibaba/RedisShake/internal/config" |
|
|
|
|
"github.com/alibaba/RedisShake/internal/log" |
|
|
|
|
"net/http" |
|
|
|
|
"time" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
|
// ID
|
|
|
|
|
entryId uint64 |
|
|
|
|
type metrics struct { |
|
|
|
|
// entries
|
|
|
|
|
EntryId uint64 `json:"entry_id"` |
|
|
|
|
AllowEntriesCount uint64 `json:"allow_entries_count"` |
|
|
|
|
DisallowEntriesCount uint64 `json:"disallow_entries_count"` |
|
|
|
|
|
|
|
|
|
// rdb
|
|
|
|
|
rdbFileSize int64 |
|
|
|
|
rdbReceivedSize int64 |
|
|
|
|
rdbSendSize int64 |
|
|
|
|
RdbFileSize uint64 `json:"rdb_file_size"` |
|
|
|
|
RdbReceivedSize uint64 `json:"rdb_received_size"` |
|
|
|
|
RdbSendSize uint64 `json:"rdb_send_size"` |
|
|
|
|
|
|
|
|
|
// aof
|
|
|
|
|
aofReceivedOffset int64 |
|
|
|
|
aofAppliedOffset int64 |
|
|
|
|
// ops
|
|
|
|
|
allowEntriesCount int64 |
|
|
|
|
disallowEntriesCount int64 |
|
|
|
|
unansweredBytesCount uint64 |
|
|
|
|
) |
|
|
|
|
AofReceivedOffset uint64 `json:"aof_received_offset"` |
|
|
|
|
AofAppliedOffset uint64 `json:"aof_applied_offset"` |
|
|
|
|
|
|
|
|
|
// for performance debug
|
|
|
|
|
InQueueEntriesCount uint64 `json:"in_queue_entries_count"` |
|
|
|
|
UnansweredBytesCount uint64 `json:"unanswered_bytes_count"` |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var Metrics = &metrics{} |
|
|
|
|
|
|
|
|
|
func Handler(w http.ResponseWriter, _ *http.Request) { |
|
|
|
|
w.Header().Add("Content-Type", "application/json") |
|
|
|
|
err := json.NewEncoder(w).Encode(Metrics) |
|
|
|
|
if err != nil { |
|
|
|
|
log.PanicError(err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func Init() { |
|
|
|
|
go func() { |
|
|
|
@ -29,64 +45,84 @@ func Init() { |
|
|
|
|
log.Infof("statistics disabled. seconds=[%d]", seconds) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
lastAllowEntriesCount := Metrics.AllowEntriesCount |
|
|
|
|
lastDisallowEntriesCount := Metrics.DisallowEntriesCount |
|
|
|
|
|
|
|
|
|
for range time.Tick(time.Duration(seconds) * time.Second) { |
|
|
|
|
if rdbFileSize == 0 { |
|
|
|
|
if Metrics.RdbFileSize == 0 { |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
if rdbFileSize > rdbReceivedSize { |
|
|
|
|
if Metrics.RdbSendSize > Metrics.RdbReceivedSize { |
|
|
|
|
log.Infof("receiving rdb. percent=[%.2f]%%, rdbFileSize=[%.3f]G, rdbReceivedSize=[%.3f]G", |
|
|
|
|
float64(rdbReceivedSize)/float64(rdbFileSize)*100, |
|
|
|
|
float64(rdbFileSize)/1024/1024/1024, |
|
|
|
|
float64(rdbReceivedSize)/1024/1024/1024) |
|
|
|
|
} else if rdbFileSize > rdbSendSize { |
|
|
|
|
log.Infof("syncing rdb. percent=[%.2f]%%, allowOps=[%.2f], disallowOps=[%.2f], entryId=[%d], unansweredBytesCount=[%d]bytes, rdbFileSize=[%.3f]G, rdbSendSize=[%.3f]G", |
|
|
|
|
float64(rdbSendSize)*100/float64(rdbFileSize), |
|
|
|
|
float32(allowEntriesCount)/float32(seconds), |
|
|
|
|
float32(disallowEntriesCount)/float32(seconds), |
|
|
|
|
entryId, |
|
|
|
|
unansweredBytesCount, |
|
|
|
|
float64(rdbFileSize)/1024/1024/1024, |
|
|
|
|
float64(rdbSendSize)/1024/1024/1024) |
|
|
|
|
float64(Metrics.RdbReceivedSize)/float64(Metrics.RdbFileSize)*100, |
|
|
|
|
float64(Metrics.RdbFileSize)/1024/1024/1024, |
|
|
|
|
float64(Metrics.RdbReceivedSize)/1024/1024/1024) |
|
|
|
|
} else if Metrics.RdbFileSize > Metrics.RdbSendSize { |
|
|
|
|
log.Infof("syncing rdb. percent=[%.2f]%%, allowOps=[%.2f], disallowOps=[%.2f], entryId=[%d], InQueueEntriesCount=[%d], unansweredBytesCount=[%d]bytes, rdbFileSize=[%.3f]G, rdbSendSize=[%.3f]G", |
|
|
|
|
float64(Metrics.RdbSendSize)*100/float64(Metrics.RdbFileSize), |
|
|
|
|
float32(Metrics.AllowEntriesCount-lastAllowEntriesCount)/float32(seconds), |
|
|
|
|
float32(Metrics.DisallowEntriesCount-lastDisallowEntriesCount)/float32(seconds), |
|
|
|
|
Metrics.EntryId, |
|
|
|
|
Metrics.InQueueEntriesCount, |
|
|
|
|
Metrics.UnansweredBytesCount, |
|
|
|
|
float64(Metrics.RdbFileSize)/1024/1024/1024, |
|
|
|
|
float64(Metrics.RdbSendSize)/1024/1024/1024) |
|
|
|
|
} else { |
|
|
|
|
log.Infof("syncing aof. allowOps=[%.2f], disallowOps=[%.2f], entryId=[%d], unansweredBytesCount=[%d]bytes, diff=[%d], aofReceivedOffset=[%d], aofAppliedOffset=[%d]", |
|
|
|
|
float32(allowEntriesCount)/float32(seconds), |
|
|
|
|
float32(disallowEntriesCount)/float32(seconds), |
|
|
|
|
entryId, |
|
|
|
|
unansweredBytesCount, |
|
|
|
|
aofReceivedOffset-aofAppliedOffset, |
|
|
|
|
aofReceivedOffset, |
|
|
|
|
aofAppliedOffset) |
|
|
|
|
log.Infof("syncing aof. allowOps=[%.2f], disallowOps=[%.2f], entryId=[%d], InQueueEntriesCount=[%d], unansweredBytesCount=[%d]bytes, diff=[%d], aofReceivedOffset=[%d], aofAppliedOffset=[%d]", |
|
|
|
|
float32(Metrics.AllowEntriesCount)/float32(seconds), |
|
|
|
|
float32(Metrics.DisallowEntriesCount)/float32(seconds), |
|
|
|
|
Metrics.EntryId, |
|
|
|
|
Metrics.InQueueEntriesCount, |
|
|
|
|
Metrics.UnansweredBytesCount, |
|
|
|
|
Metrics.AofReceivedOffset-Metrics.AofAppliedOffset, |
|
|
|
|
Metrics.AofReceivedOffset, |
|
|
|
|
Metrics.AofAppliedOffset) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
allowEntriesCount = 0 |
|
|
|
|
disallowEntriesCount = 0 |
|
|
|
|
lastAllowEntriesCount = Metrics.AllowEntriesCount |
|
|
|
|
lastDisallowEntriesCount = Metrics.DisallowEntriesCount |
|
|
|
|
} |
|
|
|
|
}() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// entry id
|
|
|
|
|
|
|
|
|
|
func UpdateEntryId(id uint64) { |
|
|
|
|
entryId = id |
|
|
|
|
Metrics.EntryId = id |
|
|
|
|
} |
|
|
|
|
func AddAllowEntriesCount() { |
|
|
|
|
allowEntriesCount++ |
|
|
|
|
Metrics.AllowEntriesCount++ |
|
|
|
|
} |
|
|
|
|
func AddDisallowEntriesCount() { |
|
|
|
|
disallowEntriesCount++ |
|
|
|
|
Metrics.DisallowEntriesCount++ |
|
|
|
|
} |
|
|
|
|
func SetRDBFileSize(size int64) { |
|
|
|
|
rdbFileSize = size |
|
|
|
|
|
|
|
|
|
// rdb
|
|
|
|
|
|
|
|
|
|
func SetRDBFileSize(size uint64) { |
|
|
|
|
Metrics.RdbFileSize = size |
|
|
|
|
} |
|
|
|
|
func UpdateRDBReceivedSize(size int64) { |
|
|
|
|
rdbReceivedSize = size |
|
|
|
|
func UpdateRDBReceivedSize(size uint64) { |
|
|
|
|
Metrics.RdbReceivedSize = size |
|
|
|
|
} |
|
|
|
|
func UpdateRDBSentSize(offset int64) { |
|
|
|
|
rdbSendSize = offset |
|
|
|
|
func UpdateRDBSentSize(offset uint64) { |
|
|
|
|
Metrics.RdbSendSize = offset |
|
|
|
|
} |
|
|
|
|
func UpdateAOFReceivedOffset(offset int64) { |
|
|
|
|
aofReceivedOffset = offset |
|
|
|
|
|
|
|
|
|
// aof
|
|
|
|
|
|
|
|
|
|
func UpdateAOFReceivedOffset(offset uint64) { |
|
|
|
|
Metrics.AofReceivedOffset = offset |
|
|
|
|
} |
|
|
|
|
func UpdateAOFAppliedOffset(offset uint64) { |
|
|
|
|
Metrics.AofAppliedOffset = offset |
|
|
|
|
} |
|
|
|
|
func UpdateAOFAppliedOffset(offset int64) { |
|
|
|
|
aofAppliedOffset = offset |
|
|
|
|
|
|
|
|
|
// for debug
|
|
|
|
|
|
|
|
|
|
func UpdateInQueueEntriesCount(count uint64) { |
|
|
|
|
Metrics.InQueueEntriesCount = count |
|
|
|
|
} |
|
|
|
|
func UpdateUnansweredBytesCount(count uint64) { |
|
|
|
|
unansweredBytesCount = count |
|
|
|
|
Metrics.UnansweredBytesCount = count |
|
|
|
|
} |
|
|
|
|