2
2
a-page-header( title ="Pipeline Configuration" : show- back= "false" )
3
3
4
4
a-alert Pipeline is a mechanism in GreptimeDB for parsing and transforming log data, <a href =" https://docs.greptime.com/user-guide/logs/pipeline-config" target =" _blank" >read more</a >
5
- a-layout( style ="box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.08)" )
6
- a-layout-sider( :resize-directions ="['right']" : width= "650 " )
5
+ a-layout.full-height-layout ( style ="box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.08)" )
6
+ a-layout-sider( :resize-directions ="['right']" : width= "800 " )
7
7
a-card( title ="Pipeline" : bordered= "false" )
8
8
template( #extra )
9
9
a-space
@@ -25,52 +25,58 @@ a-layout(style="box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.08)")
25
25
:disabled ="!isCreating"
26
26
:rules ="rules"
27
27
)
28
+ .form-description Input the pipeline configuration here to define how logs are parsed and transformed, You can test on the right side whether it's already saved.
28
29
a-form-item( field ="name" label ="Pipeline name" style ="width: 200px" )
29
30
a-input( v-model ="currFile.name" placeholder ="Pipeline name" )
30
31
a-form-item( v-if ="!isCreating" field ="version" label ="Version" )
31
32
| {{ currFile.version }}
32
33
a-form-item( field ="content" label ="Yaml Content" )
33
34
template( #help )
34
35
div
35
- YMLEditorSimple( v-model ="currFile.content" style ="width: 100%; height: 525px" )
36
+ .editor-container
37
+ YMLEditorSimple( v-model ="currFile.content" style ="width: 100%; height: calc(-470px + 100vh)" )
36
38
a-layout-content
37
- div ( style = "display: flex; flex-direction: column" )
38
- a-card.light-editor-card ( title ="Input" style = "flex: 1" : bordered= "false" )
39
+ .content-container
40
+ a-card.light-editor-card ( title ="Input" : bordered= "false" )
39
41
template( #extra )
40
42
a-space
41
43
a-button( size ="small" @click ="handleDebug" ) Test
42
- //- a(href="https://github.com/GreptimeTeam/demo-scene/tree/main/vector-ingestion" target="_blank") Write Log Demo
43
-
44
+ a-select( v-model ="selectedContentType" style ="width: 150px" placeholder ="Content Type" )
45
+ a-option( value ="text/plain" ) text
46
+ a-option( value ="application/json" ) json
47
+ a-option( value ="application/x-ndjson" ) ndjson
44
48
.right-content
45
49
a-alert( v-if ="ymlError" type ="error" )
46
50
| {{ ymlError }}
47
51
a-typography-text( type ="secondary" )
48
52
| Input your original log to see parse results.
49
- CodeMirror(
50
- v-model ="debugForm.content"
51
- style ="height: 320px; width: 100%; margin-top: 5px"
52
- :extensions ="extensions"
53
- :spellcheck ="true"
54
- :autofocus ="true"
55
- :indent-with-tab ="true"
56
- :tabSize ="2"
57
- :placeholder ="debugTip"
58
- )
59
-
60
- a-card.light-editor-card ( title ="Output" style ="flex: 1" : bordered= "false" )
53
+ .input-editor
54
+ CodeMirror(
55
+ v-model ="debugForm.content"
56
+ style ="width: 100%; height: 100%"
57
+ :extensions ="extensions"
58
+ :spellcheck ="true"
59
+ :autofocus ="true"
60
+ :indent-with-tab ="true"
61
+ :tabSize ="2"
62
+ :placeholder ="debugTip"
63
+ )
64
+
65
+ a-card.light-editor-card ( title ="Output" : bordered= "false" )
61
66
.right-content
62
67
a-typography-text( type ="secondary" )
63
68
| Parsed logs displayed here. Logs that ingested via API will follow this structure.
64
- CodeMirror(
65
- style ="height: 340px; width: 100%; margin-top: 5px"
66
- :model-value ="debugResponse"
67
- :extensions ="extensions"
68
- :spellcheck ="true"
69
- :autofocus ="true"
70
- :indent-with-tab ="true"
71
- :tabSize ="2"
72
- :disabled ="true"
73
- )
69
+ .output-editor
70
+ CodeMirror(
71
+ style ="width: 100%; height: 100%"
72
+ :model-value ="debugResponse"
73
+ :extensions ="extensions"
74
+ :spellcheck ="true"
75
+ :autofocus ="true"
76
+ :indent-with-tab ="true"
77
+ :tabSize ="2"
78
+ :disabled ="true"
79
+ )
74
80
</template >
75
81
76
82
<script setup name="PipeFileView" lang="ts">
@@ -86,7 +92,6 @@ a-layout(style="box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.08)")
86
92
filename: undefined | string
87
93
}>()
88
94
89
- const debugTip = ' Input raw Strings or JSON Object Array'
90
95
const currFile = reactive <PipeFile >({
91
96
name: ' ' ,
92
97
content: ` processors:
@@ -171,19 +176,42 @@ transform:
171
176
' 210.207.142.115 - AnthraX [26/Dec/2024:16:47:19 +0800] "DELETE /do-not-access/needs-work HTTP/2.0" 200 4488' ,
172
177
})
173
178
179
+ const selectedContentType = ref (' text/plain' )
180
+ // Watch for content changes to auto-detect content type
181
+ watch (
182
+ () => debugForm .content ,
183
+ (newContent ) => {
184
+ try {
185
+ JSON .parse (newContent )
186
+ selectedContentType .value = ' application/json'
187
+ } catch (e ) {
188
+ // If content contains newlines and each line is valid JSON, it's NDJSON
189
+ if (newContent .includes (' \n ' )) {
190
+ const lines = newContent .split (' \n ' ).filter ((line ) => line .trim ())
191
+ const isNDJSON = lines .every ((line ) => {
192
+ try {
193
+ JSON .parse (line )
194
+ return true
195
+ } catch {
196
+ return false
197
+ }
198
+ })
199
+ if (isNDJSON ) {
200
+ selectedContentType .value = ' application/x-ndjson'
201
+ } else {
202
+ selectedContentType .value = ' text/plain'
203
+ }
204
+ } else {
205
+ selectedContentType .value = ' text/plain'
206
+ }
207
+ }
208
+ }
209
+ )
210
+
174
211
const extensions = [basicSetup , json ()]
175
212
const debugResponse = ref (' ' )
176
213
function handleDebug() {
177
- let content
178
- try {
179
- content = JSON .parse (debugForm .content )
180
- if (! Array .isArray (content )) {
181
- content = [content ]
182
- }
183
- } catch (e ) {
184
- content = debugForm .content .split (' \n ' )
185
- }
186
- debugContent (currFile .content , content ).then ((result ) => {
214
+ debugContent (currFile .content , debugForm .content , selectedContentType .value ).then ((result ) => {
187
215
debugResponse .value = JSON .stringify (result , null , 2 )
188
216
})
189
217
}
@@ -208,11 +236,101 @@ transform:
208
236
}
209
237
.right-content {
210
238
padding : 0 10px 10px 10px ;
239
+ height : 100% ;
240
+ display : flex ;
241
+ flex-direction : column ;
211
242
}
212
243
:deep(.arco-card.light-editor-card ) {
213
244
padding-right : 0 ;
245
+ flex : 1 ;
246
+ display : flex ;
247
+ flex-direction : column ;
248
+ min-height : 0 ;
214
249
}
215
250
:deep(.arco-layout-sider-light ) {
216
251
box-shadow : none ;
217
252
}
253
+ :deep(.arco-form-item-content-flex ) {
254
+ display : block ;
255
+ }
256
+
257
+ .content-container {
258
+ height : 100% ;
259
+ display : flex ;
260
+ flex-direction : column ;
261
+ gap : 16px ;
262
+ padding-bottom : 16px ;
263
+ }
264
+
265
+ .input-editor ,
266
+ .output-editor {
267
+ flex : 1 ;
268
+ min-height : 0 ;
269
+ margin-top : 5px ;
270
+
271
+ :deep(.cm-editor ) {
272
+ height : 100% ;
273
+ }
274
+ }
275
+
276
+ .output-editor {
277
+ :deep(.cm-editor ) {
278
+ background-color : var (--color-fill-2 );
279
+ cursor : not-allowed ;
280
+ }
281
+
282
+ :deep(.cm-content ) {
283
+ color : var (--color-text-2 );
284
+ }
285
+ }
286
+
287
+ .form-description {
288
+ color : var (--color-text-3 );
289
+ font-size : 14px ;
290
+ margin-bottom : 16px ;
291
+ }
292
+
293
+ .full-height-layout {
294
+ height : calc (100vh - 133px ); // Subtract header height and alert height
295
+
296
+ :deep(.arco-layout ) {
297
+ height : 100% ;
298
+ }
299
+
300
+ :deep(.arco-layout-content ) {
301
+ height : 100% ;
302
+ overflow : auto ;
303
+ }
304
+
305
+ :deep(.arco-layout-sider ) {
306
+ height : 100% ;
307
+ overflow : auto ;
308
+ overflow-x : hidden ; // Prevent horizontal scrollbar
309
+ }
310
+
311
+ :deep(.arco-card-body ) {
312
+ padding : 0 ; // Remove default padding that might cause overflow
313
+ height : 100% ;
314
+ }
315
+ }
316
+
317
+ .editor-container {
318
+ min-height : 300px ; // Set a minimum height
319
+ }
320
+
321
+ // Add styles for editor borders
322
+ :deep(.cm-editor ) {
323
+ border : 1px solid var (--color-border );
324
+ border-radius : 4px ;
325
+ }
326
+
327
+ :deep(.editor-container ) {
328
+ .cm-editor {
329
+ border : 1px solid var (--color-border );
330
+ border-radius : 4px ;
331
+ }
332
+ }
333
+ :deep(.cm-editor.cm-focused ) {
334
+ outline : 0 ;
335
+ }
218
336
</style >
0 commit comments