@@ -17,15 +17,15 @@ public class Summary<NumType: DoubleRepresentable, Labels: SummaryLabels>: Metri
1717 public let name : String
1818 public let help : String ?
1919
20- private var labels : Labels
20+ internal private( set ) var labels : Labels
2121
2222 private let sum : Counter < NumType , EmptyCodable >
2323
2424 private let count : Counter < NumType , EmptyCodable >
2525
2626 private var values : [ NumType ] = [ ]
2727
28- private var quantiles : [ Double ]
28+ internal let quantiles : [ Double ]
2929
3030 internal init ( _ name: String , _ help: String ? = nil , _ quantiles: [ Double ] = defaultQuantiles, _ labels: Labels = Labels ( ) , _ p: Prometheus ) {
3131 self . name = name
@@ -45,10 +45,12 @@ public class Summary<NumType: DoubleRepresentable, Labels: SummaryLabels>: Metri
4545 public func getMetric( ) -> String {
4646 var output = [ String] ( )
4747
48- if let help = help {
49- output. append ( " # HELP \( name) \( help) " )
48+ if self . labels == Labels ( ) {
49+ if let help = help {
50+ output. append ( " # HELP \( name) \( help) " )
51+ }
52+ output. append ( " # TYPE \( name) summary " )
5053 }
51- output. append ( " # TYPE \( name) summary " )
5254
5355 calculateQuantiles ( quantiles: quantiles, values: values. map { $0. doubleValue } ) . sorted { $0. key < $1. key } . forEach { ( arg) in
5456 let ( q, v) = arg
@@ -60,17 +62,40 @@ public class Summary<NumType: DoubleRepresentable, Labels: SummaryLabels>: Metri
6062 let labelsString = encodeLabels ( self . labels, [ " quantile " ] )
6163 output. append ( " \( name) _count \( labelsString) \( count. get ( ) ) " )
6264 output. append ( " \( name) _sum \( labelsString) \( sum. get ( ) ) " )
63-
65+
66+ self . labels. quantile = " "
67+
6468 return output. joined ( separator: " \n " )
6569 }
6670
67- public func observe( _ value: NumType ) {
71+ public func observe( _ value: NumType , _ labels: Labels ? = nil ) {
72+ if let labels = labels, type ( of: labels) != type ( of: EmptySummaryCodable ( ) ) {
73+ let sum = self . prometheus. getOrCreateSummary ( withLabels: labels, forSummary: self )
74+ sum. observe ( value)
75+ return
76+ }
6877 self . count. inc ( 1 )
6978 self . sum. inc ( value)
7079 self . values. append ( value)
7180 }
7281}
7382
83+ extension Prometheus {
84+ fileprivate func getOrCreateSummary< T: Numeric , U: SummaryLabels > ( withLabels labels: U , forSummary sum: Summary < T , U > ) -> Summary < T , U > {
85+ let summary = metrics. filter { ( metric) -> Bool in
86+ guard let metric = metric as? Summary < T , U > else { return false }
87+ guard metric. name == sum. name, metric. help == sum. help, metric. labels == labels else { return false }
88+ return true
89+ } as? [ Summary < T , U > ] ?? [ ]
90+ if summary. count > 2 { fatalError ( " Somehow got 2 summaries with the same data type " ) }
91+ if let summary = summary. first {
92+ return summary
93+ } else {
94+ return createSummary ( forType: T . self, named: sum. name, helpText: sum. help, quantiles: sum. quantiles, labels: labels)
95+ }
96+ }
97+ }
98+
7499func calculateQuantiles( quantiles: [ Double ] , values: [ Double ] ) -> [ Double : Double ] {
75100 let values = values. sorted ( )
76101 var quantilesMap : [ Double : Double ] = [ : ]
@@ -81,6 +106,9 @@ func calculateQuantiles(quantiles: [Double], values: [Double]) -> [Double: Doubl
81106}
82107
83108func quantile( _ q: Double , _ values: [ Double ] ) -> Double {
109+ if values. count == 0 {
110+ return 0
111+ }
84112 if values. count == 1 {
85113 return values [ 0 ]
86114 }
0 commit comments