diff --git a/protocol/lib/metrics/constants.go b/protocol/lib/metrics/constants.go index dff52b62c01..c988e626aa3 100644 --- a/protocol/lib/metrics/constants.go +++ b/protocol/lib/metrics/constants.go @@ -302,7 +302,6 @@ const ( // Liquidation. ConstructLiquidationOrder = "construct_liquidation_order" - InsuranceFundBalance = "insurance_fund_balance" InsuranceFundDelta = "insurance_fund_delta" Liquidations = "liquidations" MaybeGetLiquidationOrder = "maybe_get_liquidation_order" diff --git a/protocol/lib/metrics/lib.go b/protocol/lib/metrics/lib.go new file mode 100644 index 00000000000..bd67d1c41ee --- /dev/null +++ b/protocol/lib/metrics/lib.go @@ -0,0 +1,92 @@ +package metrics + +import ( + "time" + + gometrics "github.com/armon/go-metrics" + "github.com/cosmos/cosmos-sdk/telemetry" +) + +// This file provides a main entrypoint for logging in the v4 protocol. +// TODO(CLOB-1013) Drop both metrics libraries above for a library +// that supports float64 (i.e hashicorp go-metrics) + +type Label = gometrics.Label + +// IncrCounterWithLabels provides a wrapper functionality for emitting a counter +// metric with global labels (if any) along with the provided labels. +func IncrCounterWithLabels(key string, val float32, labels ...Label) { + telemetry.IncrCounterWithLabels([]string{key}, val, labels) +} + +// IncrCounter provides a wrapper functionality for emitting a counter +// metric with global labels (if any). +func IncrCounter(key string, val float32) { + telemetry.IncrCounterWithLabels([]string{key}, val, []gometrics.Label{}) +} + +// SetGaugeWithLabels provides a wrapper functionality for emitting a gauge +// metric with global labels (if any) along with the provided labels. +func SetGaugeWithLabels(key string, val float32, labels ...gometrics.Label) { + telemetry.SetGaugeWithLabels([]string{key}, val, labels) +} + +// SetGauge provides a wrapper functionality for emitting a gauge +// metric with global labels (if any). +func SetGauge(key string, val float32) { + telemetry.SetGaugeWithLabels([]string{key}, val, []gometrics.Label{}) +} + +// AddSampleWithLabels provides a wrapper functionality for emitting a sample +// metric with the provided labels. +func AddSampleWithLabels(key string, val float32, labels ...gometrics.Label) { + gometrics.AddSampleWithLabels( + []string{key}, + val, + labels, + ) +} + +// AddSample provides a wrapper functionality for emitting a sample +// metric. +func AddSample(key string, val float32) { + gometrics.AddSampleWithLabels( + []string{key}, + val, + []gometrics.Label{}, + ) +} + +// ModuleMeasureSince provides a wrapper functionality for emitting a time measure +// metric with global labels (if any). +// Please try to use `AddSample` instead. +// TODO(CLOB-1022) Roll our own calculations for timing on top of AddSample instead +// of using MeasureSince. +func ModuleMeasureSince(module string, key string, start time.Time) { + telemetry.ModuleMeasureSince( + module, + start, + key, + ) +} + +// ModuleMeasureSinceWithLabels provides a short hand method for emitting a time measure +// metric for a module with labels. Global labels are not included in this metric. +// Please try to use `AddSampleWithLabels` instead. +// TODO(CLOB-1022) Roll our own calculations for timing on top of AddSample instead +// of using MeasureSince. +func ModuleMeasureSinceWithLabels( + module string, + keys []string, + start time.Time, + labels []gometrics.Label, +) { + gometrics.MeasureSinceWithLabels( + keys, + start.UTC(), + append( + []gometrics.Label{telemetry.NewLabel(telemetry.MetricLabelNameModule, module)}, + labels..., + ), + ) +} diff --git a/protocol/lib/metrics/metric_keys.go b/protocol/lib/metrics/metric_keys.go new file mode 100644 index 00000000000..1be6e8f7177 --- /dev/null +++ b/protocol/lib/metrics/metric_keys.go @@ -0,0 +1,42 @@ +// nolint:lll +package metrics + +// Metrics Keys Guidelines +// 1. Be wary of length +// 2. Prefix by module +// 3. Suffix keys with a unit of measurement +// 4. Delimit with '_' +// 5. Information such as callback type should be added as tags, not in key names. +// Example: clob_place_order_count, clob_msg_place_order_latency_ms, clob_operations_queue_length +// clob_expired_stateful_orders_count, clob_processed_orders_ms_total + +// Clob Metrics Keys +const ( + // Stats + ClobExpiredStatefulOrders = "clob_expired_stateful_order_removed" + ClobPrepareCheckStateCannotDeleverageSubaccount = "clob_prepare_check_state_cannot_deleverage_subaccount" + ClobDeleverageSubaccountTotalQuoteQuantums = "clob_deleverage_subaccount_total_quote_quantums" + ClobDeleverageSubaccount = "clob_deleverage_subaccount" + LiquidationsPlacePerpetualLiquidationQuoteQuantums = "liquidations_place_perpetual_liquidation_quote_quantums" + LiquidationsLiquidationMatchNegativeTNC = "liquidations_liquidation_match_negative_tnc" + ClobMevErrorCount = "clob_mev_error_count" + + // Gauges + InsuranceFundBalance = "insurance_fund_balance" + ClobMev = "clob_mev" + + // Samples + ClobDeleverageSubaccountTotalQuoteQuantumsDistribution = "clob_deleverage_subaccount_total_quote_quantums_distribution" + DeleveragingPercentFilledDistribution = "deleveraging_percent_filled_distribution" + ClobDeleveragingNumSubaccountsIteratedCount = "clob_deleveraging_num_subaccounts_iterated_count" + ClobDeleveragingNonOverlappingBankrupcyPricesCount = "clob_deleveraging_non_overlapping_bankruptcy_prices_count" + ClobDeleveragingNoOpenPositionOnOppositeSideCount = "clob_deleveraging_no_open_position_on_opposite_side_count" + ClobDeleverageSubaccountFilledQuoteQuantums = "clob_deleverage_subaccount_filled_quote_quantums" + LiquidationsLiquidatableSubaccountIdsCount = "liquidations_liquidatable_subaccount_ids_count" + LiquidationsPercentFilledDistribution = "liquidations_percent_filled_distribution" + LiquidationsPlacePerpetualLiquidationQuoteQuantumsDistribution = "liquidations_place_perpetual_liquidation_quote_quantums_distribution" + + // Measure Since + ClobOffsettingSubaccountPerpetualPosition = "clob_offsetting_subaccount_perpetual_position" + MevLatency = "mev_latency" +) diff --git a/protocol/lib/metrics/util.go b/protocol/lib/metrics/util.go index 3d7d71682bb..cd16b4261b3 100644 --- a/protocol/lib/metrics/util.go +++ b/protocol/lib/metrics/util.go @@ -3,7 +3,6 @@ package metrics import ( "math/big" "strconv" - "time" sdk "github.com/cosmos/cosmos-sdk/types" @@ -68,25 +67,6 @@ func GetMetricValueFromBigInt(i *big.Int) float32 { return r } -// ModuleMeasureSinceWithLabels provides a short hand method for emitting a time measure -// metric for a module with a given set of keys and labels. -// NOTE: global labels are not included in this metric. -func ModuleMeasureSinceWithLabels( - module string, - keys []string, - start time.Time, - labels []gometrics.Label, -) { - gometrics.MeasureSinceWithLabels( - keys, - start.UTC(), - append( - []gometrics.Label{telemetry.NewLabel(telemetry.MetricLabelNameModule, module)}, - labels..., - ), - ) -} - // GetCallbackMetricFromCtx determines the callback metric based on the context. Note that DeliverTx is implied // if the context is not CheckTx or ReCheckTx. This function is unable to account for other callbacks like // PrepareCheckState or EndBlocker. diff --git a/protocol/x/clob/abci.go b/protocol/x/clob/abci.go index f8e89134ce3..b22303d983a 100644 --- a/protocol/x/clob/abci.go +++ b/protocol/x/clob/abci.go @@ -4,7 +4,6 @@ import ( "fmt" "time" - gometrics "github.com/armon/go-metrics" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" liquidationtypes "github.com/dydxprotocol/v4-chain/protocol/daemons/server/types/liquidations" @@ -63,10 +62,10 @@ func EndBlocker( ), ), ) - telemetry.IncrCounterWithLabels( - []string{types.ModuleName, metrics.Expired, metrics.StatefulOrderRemoved, metrics.Count}, + metrics.IncrCounterWithLabels( + metrics.ClobExpiredStatefulOrders, 1, - orderId.GetOrderIdLabels(), + orderId.GetOrderIdLabels()..., ) } @@ -108,10 +107,9 @@ func EndBlocker( keeper.PruneRateLimits(ctx) // Emit relevant metrics at the end of every block. - telemetry.SetGaugeWithLabels( - []string{metrics.InsuranceFundBalance}, + metrics.SetGauge( + metrics.InsuranceFundBalance, metrics.GetMetricValueFromBigInt(keeper.GetInsuranceFundBalance(ctx)), - []gometrics.Label{}, ) } diff --git a/protocol/x/clob/keeper/deleveraging.go b/protocol/x/clob/keeper/deleveraging.go index 50e055e3ab0..794d2ff8350 100644 --- a/protocol/x/clob/keeper/deleveraging.go +++ b/protocol/x/clob/keeper/deleveraging.go @@ -3,15 +3,14 @@ package keeper import ( "errors" "fmt" - indexerevents "github.com/dydxprotocol/v4-chain/protocol/indexer/events" - "github.com/dydxprotocol/v4-chain/protocol/indexer/indexer_manager" "math/big" "time" + indexerevents "github.com/dydxprotocol/v4-chain/protocol/indexer/events" + "github.com/dydxprotocol/v4-chain/protocol/indexer/indexer_manager" + errorsmod "cosmossdk.io/errors" - gometrics "github.com/armon/go-metrics" - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/dydxprotocol/v4-chain/protocol/lib" "github.com/dydxprotocol/v4-chain/protocol/lib/metrics" @@ -41,11 +40,9 @@ func (k Keeper) MaybeDeleverageSubaccount( // Early return to skip deleveraging if the subaccount can't be deleveraged. if !canPerformDeleveraging { - telemetry.IncrCounter( + metrics.IncrCounter( + metrics.ClobPrepareCheckStateCannotDeleverageSubaccount, 1, - types.ModuleName, - metrics.PrepareCheckState, - metrics.CannotDeleverageSubaccount, ) return new(big.Int), nil } @@ -67,7 +64,7 @@ func (k Keeper) MaybeDeleverageSubaccount( deltaQuantums := new(big.Int).Neg(position.GetBigQuantums()) quantumsDeleveraged, err = k.MemClob.DeleverageSubaccount(ctx, subaccountId, perpetualId, deltaQuantums) - labels := []gometrics.Label{ + labels := []metrics.Label{ metrics.GetLabelForIntValue(metrics.PerpetualId, int(perpetualId)), metrics.GetLabelForBoolValue(metrics.IsLong, deltaQuantums.Sign() == -1), } @@ -79,22 +76,27 @@ func (k Keeper) MaybeDeleverageSubaccount( labels = append(labels, metrics.GetLabelForStringValue(metrics.Status, metrics.PartiallyFilled)) } // Record the status of the deleveraging operation. - telemetry.IncrCounterWithLabels([]string{types.ModuleName, metrics.DeleverageSubaccount}, 1, labels) + metrics.IncrCounterWithLabels( + metrics.ClobDeleverageSubaccount, + 1, + labels..., + ) if quoteQuantums, err := k.perpetualsKeeper.GetNetNotional( ctx, perpetualId, new(big.Int).Abs(deltaQuantums), ); err == nil { - telemetry.IncrCounterWithLabels( - []string{types.ModuleName, metrics.DeleverageSubaccount, metrics.TotalQuoteQuantums}, + metrics.IncrCounterWithLabels( + metrics.ClobDeleverageSubaccountTotalQuoteQuantums, metrics.GetMetricValueFromBigInt(quoteQuantums), - labels, + labels..., ) - gometrics.AddSampleWithLabels( - []string{types.ModuleName, metrics.DeleverageSubaccount, metrics.TotalQuoteQuantums, metrics.Distribution}, + + metrics.AddSampleWithLabels( + metrics.ClobDeleverageSubaccountTotalQuoteQuantumsDistribution, metrics.GetMetricValueFromBigInt(quoteQuantums), - labels, + labels..., ) } @@ -103,10 +105,11 @@ func (k Keeper) MaybeDeleverageSubaccount( new(big.Float).SetInt(new(big.Int).Abs(quantumsDeleveraged)), new(big.Float).SetInt(new(big.Int).Abs(deltaQuantums)), ).Float32() - gometrics.AddSampleWithLabels( - []string{metrics.Deleveraging, metrics.PercentFilled, metrics.Distribution}, + + metrics.AddSampleWithLabels( + metrics.DeleveragingPercentFilledDistribution, percentFilled, - labels, + labels..., ) return quantumsDeleveraged, err @@ -195,11 +198,10 @@ func (k Keeper) OffsetSubaccountPerpetualPosition( fills []types.MatchPerpetualDeleveraging_Fill, deltaQuantumsRemaining *big.Int, ) { - defer telemetry.ModuleMeasureSince( + defer metrics.ModuleMeasureSince( types.ModuleName, + metrics.ClobOffsettingSubaccountPerpetualPosition, time.Now(), - types.ModuleName, - metrics.OffsettingSubaccountPerpetualPosition, ) numSubaccountsIterated := uint32(0) @@ -280,29 +282,25 @@ func (k Keeper) OffsetSubaccountPerpetualPosition( k.GetPseudoRand(ctx), ) - labels := []gometrics.Label{ + labels := []metrics.Label{ metrics.GetLabelForIntValue(metrics.PerpetualId, int(perpetualId)), } - gometrics.AddSampleWithLabels( - []string{ - types.ModuleName, metrics.Deleveraging, metrics.NumSubaccountsIterated, metrics.Count, - }, + + metrics.AddSampleWithLabels( + metrics.ClobDeleveragingNumSubaccountsIteratedCount, float32(numSubaccountsIterated), - labels, + labels..., ) - gometrics.AddSampleWithLabels( - []string{ - types.ModuleName, metrics.Deleveraging, metrics.NonOverlappingBankruptcyPrices, metrics.Count, - }, + + metrics.AddSampleWithLabels( + metrics.ClobDeleveragingNonOverlappingBankrupcyPricesCount, float32(numSubaccountsWithNonOverlappingBankruptcyPrices), - labels, + labels..., ) - gometrics.AddSampleWithLabels( - []string{ - types.ModuleName, metrics.Deleveraging, metrics.NoOpenPositionOnOppositeSide, metrics.Count, - }, + metrics.AddSampleWithLabels( + metrics.ClobDeleveragingNoOpenPositionOnOppositeSideCount, float32(numSubaccountsWithNoOpenPositionOnOppositeSide), - labels, + labels..., ) return fills, deltaQuantumsRemaining } @@ -423,15 +421,16 @@ func (k Keeper) ProcessDeleveraging( perpetualId, new(big.Int).Abs(deltaQuantums), ); err == nil { - labels := []gometrics.Label{ + labels := []metrics.Label{ metrics.GetLabelForIntValue(metrics.PerpetualId, int(perpetualId)), metrics.GetLabelForBoolValue(metrics.CheckTx, ctx.IsCheckTx()), metrics.GetLabelForBoolValue(metrics.IsLong, deltaQuantums.Sign() == -1), } - gometrics.AddSampleWithLabels( - []string{types.ModuleName, metrics.DeleverageSubaccount, metrics.Filled, metrics.QuoteQuantums}, + + metrics.AddSampleWithLabels( + metrics.ClobDeleverageSubaccountFilledQuoteQuantums, metrics.GetMetricValueFromBigInt(deleveragedQuoteQuantums), - labels, + labels..., ) } diff --git a/protocol/x/clob/keeper/liquidations.go b/protocol/x/clob/keeper/liquidations.go index eb5d4190b86..8017370cfa9 100644 --- a/protocol/x/clob/keeper/liquidations.go +++ b/protocol/x/clob/keeper/liquidations.go @@ -10,7 +10,6 @@ import ( errorsmod "cosmossdk.io/errors" - gometrics "github.com/armon/go-metrics" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/dydxprotocol/v4-chain/protocol/lib" @@ -28,12 +27,8 @@ func (k Keeper) LiquidateSubaccountsAgainstOrderbook( ) error { lib.AssertCheckTxMode(ctx) - gometrics.AddSample( - []string{ - metrics.Liquidations, - metrics.LiquidatableSubaccountIds, - metrics.Count, - }, + metrics.AddSample( + metrics.LiquidationsLiquidatableSubaccountIdsCount, float32(len(subaccountIds)), ) @@ -284,7 +279,7 @@ func (k Keeper) PlacePerpetualLiquidation( perpetualId, ) - labels := []gometrics.Label{ + labels := []metrics.Label{ metrics.GetLabelForIntValue(metrics.PerpetualId, int(perpetualId)), } if liquidationOrder.IsBuy() { @@ -298,10 +293,11 @@ func (k Keeper) PlacePerpetualLiquidation( new(big.Float).SetUint64(orderSizeOptimisticallyFilledFromMatchingQuantums.ToUint64()), new(big.Float).SetUint64(liquidationOrder.GetBaseQuantums().ToUint64()), ).Float32() - gometrics.AddSampleWithLabels( - []string{metrics.Liquidations, metrics.PercentFilled, metrics.Distribution}, + + metrics.AddSampleWithLabels( + metrics.LiquidationsPercentFilledDistribution, percentFilled, - labels, + labels..., ) if orderSizeOptimisticallyFilledFromMatchingQuantums == 0 { @@ -324,15 +320,16 @@ func (k Keeper) PlacePerpetualLiquidation( perpetualId, liquidationOrder.GetBaseQuantums().ToBigInt(), ); err == nil { - telemetry.IncrCounterWithLabels( - []string{metrics.Liquidations, metrics.PlacePerpetualLiquidation, metrics.QuoteQuantums}, + metrics.IncrCounterWithLabels( + metrics.LiquidationsPlacePerpetualLiquidationQuoteQuantums, metrics.GetMetricValueFromBigInt(totalQuoteQuantums), - labels, + labels..., ) - gometrics.AddSampleWithLabels( - []string{metrics.Liquidations, metrics.PlacePerpetualLiquidation, metrics.QuoteQuantums, metrics.Distribution}, + + metrics.AddSampleWithLabels( + metrics.LiquidationsPlacePerpetualLiquidationQuoteQuantumsDistribution, metrics.GetMetricValueFromBigInt(totalQuoteQuantums), - labels, + labels..., ) } @@ -581,19 +578,18 @@ func (k Keeper) GetFillablePrice( if !ctx.IsCheckTx() && !ctx.IsReCheckTx() { callback = metrics.DeliverTx } - telemetry.IncrCounterWithLabels( - []string{metrics.Liquidations, metrics.LiquidationMatchNegativeTNC}, + + metrics.IncrCounterWithLabels( + metrics.LiquidationsLiquidationMatchNegativeTNC, 1, - []gometrics.Label{ - metrics.GetLabelForIntValue( - metrics.PerpetualId, - int(perpetualId), - ), - metrics.GetLabelForStringValue( - metrics.Callback, - callback, - ), - }, + metrics.GetLabelForIntValue( + metrics.PerpetualId, + int(perpetualId), + ), + metrics.GetLabelForStringValue( + metrics.Callback, + callback, + ), ) ctx.Logger().Info( diff --git a/protocol/x/clob/keeper/mev.go b/protocol/x/clob/keeper/mev.go index f1015c4ecb0..870dc0e0f18 100644 --- a/protocol/x/clob/keeper/mev.go +++ b/protocol/x/clob/keeper/mev.go @@ -6,8 +6,6 @@ import ( "runtime/debug" "time" - gometrics "github.com/armon/go-metrics" - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/dydxprotocol/v4-chain/protocol/app/process" "github.com/dydxprotocol/v4-chain/protocol/lib" @@ -60,7 +58,11 @@ func (k Keeper) RecordMevMetrics( perpetualKeeper process.ProcessPerpetualKeeper, msgProposedOperations *types.MsgProposedOperations, ) { - defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), metrics.Mev, metrics.Latency) + defer metrics.ModuleMeasureSince( + types.ModuleName, + metrics.MevLatency, + time.Now(), + ) // Recover from any panics that occur during MEV calculation. defer func() { @@ -99,7 +101,10 @@ func (k Keeper) RecordMevMetrics( msgProposedOperations.GetOperationsQueue(), ), ) - telemetry.IncrCounter(1, types.ModuleName, metrics.Mev, metrics.Error, metrics.Count) + metrics.IncrCounter( + metrics.ClobMevErrorCount, + 1, + ) return } if err := k.CalculateSubaccountPnLForMevMatches( @@ -114,7 +119,10 @@ func (k Keeper) RecordMevMetrics( blockProposerMevMatches, ), ) - telemetry.IncrCounter(1, types.ModuleName, metrics.Mev, metrics.Error, metrics.Count) + metrics.IncrCounter( + metrics.ClobMevErrorCount, + 1, + ) return } @@ -132,7 +140,10 @@ func (k Keeper) RecordMevMetrics( k.GetOperations(ctx).GetOperationsQueue(), ), ) - telemetry.IncrCounter(1, types.ModuleName, metrics.Mev, metrics.Error, metrics.Count) + metrics.IncrCounter( + metrics.ClobMevErrorCount, + 1, + ) return } if err := k.CalculateSubaccountPnLForMevMatches( @@ -147,7 +158,10 @@ func (k Keeper) RecordMevMetrics( validatorMevMatches, ), ) - telemetry.IncrCounter(1, types.ModuleName, metrics.Mev, metrics.Error, metrics.Count) + metrics.IncrCounter( + metrics.ClobMevErrorCount, + 1, + ) return } @@ -220,7 +234,10 @@ func (k Keeper) RecordMevMetrics( consensusRound, ok := ctx.Value(process.ConsensusRound).(int64) if !ok { k.Logger(ctx).Error("Failed to get consensus round") - telemetry.IncrCounter(1, types.ModuleName, metrics.Mev, metrics.Error, metrics.Count) + metrics.IncrCounter( + metrics.ClobMevErrorCount, + 1, + ) return } @@ -233,7 +250,10 @@ func (k Keeper) RecordMevMetrics( "proposer", proposerConsAddress.String(), ) - telemetry.IncrCounter(1, types.ModuleName, metrics.Mev, metrics.Error, metrics.Count) + metrics.IncrCounter( + metrics.ClobMevErrorCount, + 1, + ) return } @@ -280,19 +300,17 @@ func (k Keeper) RecordMevMetrics( ).String(), ) - telemetry.SetGaugeWithLabels( - []string{types.ModuleName, metrics.Mev}, + metrics.SetGaugeWithLabels( + metrics.ClobMev, mev, - []gometrics.Label{ - metrics.GetLabelForStringValue( - metrics.Proposer, - proposer.Description.Moniker, - ), - metrics.GetLabelForIntValue( - metrics.ClobPairId, - int(clobPairId.ToUint32()), - ), - }, + metrics.GetLabelForStringValue( + metrics.Proposer, + proposer.Description.Moniker, + ), + metrics.GetLabelForIntValue( + metrics.ClobPairId, + int(clobPairId.ToUint32()), + ), ) validatorVolumeQuoteQuantumsPerMarket[clobPairId] = new(big.Int).Div( diff --git a/protocol/x/clob/types/order_id.go b/protocol/x/clob/types/order_id.go index ee74f7aacf1..8f629a12369 100644 --- a/protocol/x/clob/types/order_id.go +++ b/protocol/x/clob/types/order_id.go @@ -6,7 +6,6 @@ import ( errorsmod "cosmossdk.io/errors" - gometrics "github.com/armon/go-metrics" "github.com/dydxprotocol/v4-chain/protocol/lib/metrics" ) @@ -174,8 +173,8 @@ func MustSortAndHaveNoDuplicates(orderIds []OrderId) { } // GetOrderIdLabels returns the telemetry labels of this order ID. -func (o *OrderId) GetOrderIdLabels() []gometrics.Label { - return []gometrics.Label{ +func (o *OrderId) GetOrderIdLabels() []metrics.Label { + return []metrics.Label{ metrics.GetLabelForIntValue(metrics.OrderFlag, int(o.GetOrderFlags())), metrics.GetLabelForIntValue(metrics.ClobPairId, int(o.GetClobPairId())), }