@@ -71,146 +71,148 @@ func valueToStringArray(v pcommon.Value) ([]string, error) {
71
71
}
72
72
73
73
// Inserts a profile batch into the clickhouse server using columnar native protocol
74
- func (ch * clickhouseAccessNativeColumnar ) InsertBatch (ls plog.Logs ) error {
74
+ func (ch * clickhouseAccessNativeColumnar ) InsertBatch (ls plog.Logs ) ( int , error ) {
75
75
b , err := ch .conn .PrepareBatch (context .Background (), "INSERT INTO profiles_input" )
76
76
if err != nil {
77
- return fmt .Errorf ("failed to prepare batch: %w" , err )
78
- }
77
+ return 0 , fmt .Errorf ("failed to prepare batch: %w" , err )
78
+ }
79
+
80
+ // this implementation is tightly coupled to how pyroscope-java and pyroscopereceiver work
81
+ timestamp_ns := make ([]uint64 , 0 )
82
+ typ := make ([]string , 0 )
83
+ service_name := make ([]string , 0 )
84
+ values_agg := make ([][]tuple , 0 )
85
+ sample_types_units := make ([][]tuple , 0 )
86
+ period_type := make ([]string , 0 )
87
+ period_unit := make ([]string , 0 )
88
+ tags := make ([][]tuple , 0 )
89
+ duration_ns := make ([]uint64 , 0 )
90
+ payload_type := make ([]string , 0 )
91
+ payload := make ([][]byte , 0 )
79
92
80
- // this implementation is tightly coupled to how pyroscope-java and pyroscopereciver work,
81
- // specifically receiving a single profile at a time from the agent,
82
- // and thus each batched resource logs slice contains a single log record
83
93
rl := ls .ResourceLogs ()
84
- sz := rl .Len ()
85
-
86
- timestamp_ns := make ([]uint64 , sz )
87
- typ := make ([]string , sz )
88
- service_name := make ([]string , sz )
89
- values_agg := make ([][]tuple , sz )
90
- sample_types_units := make ([][]tuple , sz )
91
- period_type := make ([]string , sz )
92
- period_unit := make ([]string , sz )
93
- tags := make ([][]tuple , sz )
94
- duration_ns := make ([]uint64 , sz )
95
- payload_type := make ([]string , sz )
96
- payload := make ([][]byte , sz )
97
-
98
94
var (
99
- r plog.LogRecord
100
- m pcommon.Map
101
- tmp pcommon.Value
102
- tm map [string ]any
95
+ lr plog.LogRecordSlice
96
+ r plog.LogRecord
97
+ m pcommon.Map
98
+ tmp pcommon.Value
99
+ tm map [string ]any
100
+ offset int
101
+ s int
102
+ idx int
103
103
)
104
- for i := 0 ; i < sz ; i ++ {
105
- r = rl .At (i ).ScopeLogs ().At (0 ).LogRecords ().At (0 )
106
- m = r .Attributes ()
107
- timestamp_ns [i ] = uint64 (r .Timestamp ())
108
-
109
- tmp , _ = m .Get (columnType )
110
- typ [i ] = tmp .AsString ()
111
-
112
- tmp , _ = m .Get (columnServiceName )
113
- service_name [i ] = tmp .AsString ()
114
-
115
- sample_types , _ := m .Get ("sample_types" )
116
-
117
- sample_units , _ := m .Get ("sample_units" )
118
-
119
- sample_types_array , err := valueToStringArray (sample_types )
120
- if err != nil {
121
- return err
122
- }
123
-
124
- sample_units_array , err := valueToStringArray (sample_units )
125
- if err != nil {
126
- return err
127
- }
128
-
129
- values_agg_raw , ok := m .Get (columnValuesAgg )
130
- if ok {
131
- values_agg_tuple , err := valueAggToTuple (& values_agg_raw )
104
+ for i := 0 ; i < rl .Len (); i ++ {
105
+ lr = rl .At (i ).ScopeLogs ().At (0 ).LogRecords ()
106
+ for s = 0 ; s < lr .Len (); s ++ {
107
+ r = lr .At (s )
108
+ m = r .Attributes ()
109
+ timestamp_ns = append (timestamp_ns , uint64 (r .Timestamp ()))
110
+
111
+ tmp , _ = m .Get (columnType )
112
+ typ = append (typ , tmp .AsString ())
113
+
114
+ tmp , _ = m .Get (columnServiceName )
115
+ service_name = append (service_name , tmp .AsString ())
116
+
117
+ sample_types , _ := m .Get ("sample_types" )
118
+ sample_units , _ := m .Get ("sample_units" )
119
+ sample_types_array , err := valueToStringArray (sample_types )
132
120
if err != nil {
133
- return err
121
+ return 0 , err
134
122
}
135
- values_agg [i ] = append (values_agg [i ], values_agg_tuple ... )
136
- }
137
-
138
- sample_types_units_item := make ([]tuple , len (sample_types_array ))
139
- for i , v := range sample_types_array {
140
-
141
- sample_types_units_item [i ] = tuple {v , sample_units_array [i ]}
142
- }
143
- sample_types_units [i ] = sample_types_units_item
144
- tmp , _ = m .Get (columnPeriodType )
145
- period_type [i ] = tmp .AsString ()
146
-
147
- tmp , _ = m .Get (columnPeriodUnit )
148
- period_unit [i ] = tmp .AsString ()
149
-
150
- tmp , _ = m .Get (columnTags )
151
- tm = tmp .Map ().AsRaw ()
152
- tag , j := make ([]tuple , len (tm )), 0
153
- for k , v := range tm {
154
- tag [j ] = tuple {k , v .(string )}
155
- j ++
156
- }
157
- tags [i ] = tag
158
-
159
- tmp , _ = m .Get (columnDurationNs )
160
- duration_ns [i ], _ = strconv .ParseUint (tmp .Str (), 10 , 64 )
123
+ sample_units_array , err := valueToStringArray (sample_units )
124
+ if err != nil {
125
+ return 0 , err
126
+ }
127
+ values_agg_raw , ok := m .Get (columnValuesAgg )
128
+ if ok {
129
+ values_agg_tuple , err := valueAggToTuple (& values_agg_raw )
130
+ if err != nil {
131
+ return 0 , err
132
+ }
133
+ values_agg = append (values_agg , values_agg_tuple )
134
+ }
135
+ sample_types_units_item := make ([]tuple , len (sample_types_array ))
136
+ for i , v := range sample_types_array {
137
+ sample_types_units_item [i ] = tuple {v , sample_units_array [i ]}
138
+ }
139
+ sample_types_units = append (sample_types_units , sample_types_units_item )
161
140
162
- tmp , _ = m .Get (columnPayloadType )
163
- payload_type [ i ] = tmp .AsString ()
141
+ tmp , _ = m .Get (columnPeriodType )
142
+ period_type = append ( period_type , tmp .AsString () )
164
143
165
- payload [i ] = r .Body ().Bytes ().AsRaw ()
144
+ tmp , _ = m .Get (columnPeriodUnit )
145
+ period_unit = append (period_unit , tmp .AsString ())
166
146
167
- ch .logger .Debug (
168
- fmt .Sprintf ("batch insert prepared row %d" , i ),
169
- zap .Uint64 (columnTimestampNs , timestamp_ns [i ]),
170
- zap .String (columnType , typ [i ]),
171
- zap .String (columnServiceName , service_name [i ]),
172
- zap .String (columnPeriodType , period_type [i ]),
173
- zap .String (columnPeriodUnit , period_unit [i ]),
174
- zap .String (columnPayloadType , payload_type [i ]),
175
- )
147
+ tmp , _ = m .Get (columnTags )
148
+ tm = tmp .Map ().AsRaw ()
149
+ tag , j := make ([]tuple , len (tm )), 0
150
+ for k , v := range tm {
151
+ tag [j ] = tuple {k , v .(string )}
152
+ j ++
153
+ }
154
+ tags = append (tags , tag )
155
+
156
+ tmp , _ = m .Get (columnDurationNs )
157
+ dur , _ := strconv .ParseUint (tmp .Str (), 10 , 64 )
158
+ duration_ns = append (duration_ns , dur )
159
+
160
+ tmp , _ = m .Get (columnPayloadType )
161
+ payload_type = append (payload_type , tmp .AsString ())
162
+
163
+ payload = append (payload , r .Body ().Bytes ().AsRaw ())
164
+
165
+ idx = offset + s
166
+ ch .logger .Debug (
167
+ fmt .Sprintf ("batch insert prepared row %d" , idx ),
168
+ zap .Uint64 (columnTimestampNs , timestamp_ns [idx ]),
169
+ zap .String (columnType , typ [idx ]),
170
+ zap .String (columnServiceName , service_name [idx ]),
171
+ zap .String (columnPeriodType , period_type [idx ]),
172
+ zap .String (columnPeriodUnit , period_unit [idx ]),
173
+ zap .Any (columnSampleTypesUnits , sample_types_units [idx ]),
174
+ zap .String (columnPayloadType , payload_type [idx ]),
175
+ )
176
+ }
177
+ offset += s
176
178
}
177
179
178
180
// column order here should match table column order
179
181
if err := b .Column (0 ).Append (timestamp_ns ); err != nil {
180
- return err
182
+ return 0 , err
181
183
}
182
184
if err := b .Column (1 ).Append (typ ); err != nil {
183
- return err
185
+ return 0 , err
184
186
}
185
187
if err := b .Column (2 ).Append (service_name ); err != nil {
186
- return err
188
+ return 0 , err
187
189
}
188
190
if err := b .Column (3 ).Append (sample_types_units ); err != nil {
189
- return err
191
+ return 0 , err
190
192
}
191
193
if err := b .Column (4 ).Append (period_type ); err != nil {
192
- return err
194
+ return 0 , err
193
195
}
194
196
if err := b .Column (5 ).Append (period_unit ); err != nil {
195
- return err
197
+ return 0 , err
196
198
}
197
199
if err := b .Column (6 ).Append (tags ); err != nil {
198
- return err
200
+ return 0 , err
199
201
}
200
202
if err := b .Column (7 ).Append (duration_ns ); err != nil {
201
- return err
203
+ return 0 , err
202
204
}
203
205
if err := b .Column (8 ).Append (payload_type ); err != nil {
204
- return err
206
+ return 0 , err
205
207
}
206
208
207
209
if err := b .Column (9 ).Append (payload ); err != nil {
208
- return err
210
+ return 0 , err
209
211
}
210
212
if err := b .Column (10 ).Append (values_agg ); err != nil {
211
- return err
213
+ return 0 , err
212
214
}
213
- return b .Send ()
215
+ return offset , b .Send ()
214
216
}
215
217
216
218
// Closes the clickhouse connection pool
0 commit comments