(appender storage.Appender, timeMs int64)
| 125 | } |
| 126 | |
| 127 | func (c *counter) collectMetrics(appender storage.Appender, timeMs int64) error { |
| 128 | c.seriesMtx.RLock() |
| 129 | defer c.seriesMtx.RUnlock() |
| 130 | |
| 131 | for _, s := range c.series { |
| 132 | // If we are about to call Append for the first time on a series, we need |
| 133 | // to first insert a 0 value to allow Prometheus to start from a non-null |
| 134 | // value. |
| 135 | if s.isNew() { |
| 136 | // We set the timestamp of the init serie at the end of the previous minute, that way we ensure it ends in a |
| 137 | // different aggregation interval to avoid be downsampled. |
| 138 | endOfLastMinuteMs := getEndOfLastMinuteMs(timeMs) |
| 139 | _, err := appender.Append(0, s.labels, endOfLastMinuteMs, 0) |
| 140 | // Out-of-order errors occur when a series is deleted from our registry due to staleness cleanup, |
| 141 | // but still exists in Prometheus's TSDB. When the series reappears, we attempt to add the initial 0 |
| 142 | // but Prometheus already has more recent data. We ignore this error and continue with the current value. |
| 143 | if err != nil && !isOutOfOrderError(err) { |
| 144 | return err |
| 145 | } |
| 146 | s.registerSeenSeries() |
| 147 | } |
| 148 | |
| 149 | _, err := appender.Append(0, s.labels, timeMs, s.value.Load()) |
| 150 | if err != nil { |
| 151 | return err |
| 152 | } |
| 153 | |
| 154 | // TODO: support exemplars |
| 155 | } |
| 156 | |
| 157 | return nil |
| 158 | } |
| 159 | |
| 160 | func (c *counter) countActiveSeries() int { |
| 161 | c.seriesMtx.RLock() |
nothing calls this directly
no test coverage detected