getDerivedFields.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import { groupBy } from 'lodash';
  2. import { FieldType, DataFrame, ArrayVector, DataLink, Field } from '@grafana/data';
  3. import { getDataSourceSrv } from '@grafana/runtime';
  4. import { DerivedFieldConfig } from './types';
  5. export function getDerivedFields(dataFrame: DataFrame, derivedFieldConfigs: DerivedFieldConfig[]): Field[] {
  6. if (!derivedFieldConfigs.length) {
  7. return [];
  8. }
  9. const derivedFieldsGrouped = groupBy(derivedFieldConfigs, 'name');
  10. const newFields = Object.values(derivedFieldsGrouped).map(fieldFromDerivedFieldConfig);
  11. // line-field is the first string-field
  12. // NOTE: we should create some common log-frame-extra-string-field code somewhere
  13. const lineField = dataFrame.fields.find((f) => f.type === FieldType.string);
  14. if (lineField === undefined) {
  15. // if this is happening, something went wrong, let's raise an error
  16. throw new Error('invalid logs-dataframe, string-field missing');
  17. }
  18. lineField.values.toArray().forEach((line) => {
  19. for (const field of newFields) {
  20. const logMatch = line.match(derivedFieldsGrouped[field.name][0].matcherRegex);
  21. field.values.add(logMatch && logMatch[1]);
  22. }
  23. });
  24. return newFields;
  25. }
  26. /**
  27. * Transform derivedField config into dataframe field with config that contains link.
  28. */
  29. function fieldFromDerivedFieldConfig(derivedFieldConfigs: DerivedFieldConfig[]): Field<any, ArrayVector> {
  30. const dataSourceSrv = getDataSourceSrv();
  31. const dataLinks = derivedFieldConfigs.reduce((acc, derivedFieldConfig) => {
  32. // Having field.datasourceUid means it is an internal link.
  33. if (derivedFieldConfig.datasourceUid) {
  34. const dsSettings = dataSourceSrv.getInstanceSettings(derivedFieldConfig.datasourceUid);
  35. acc.push({
  36. // Will be filled out later
  37. title: derivedFieldConfig.urlDisplayLabel || '',
  38. url: '',
  39. // This is hardcoded for Jaeger or Zipkin not way right now to specify datasource specific query object
  40. internal: {
  41. query: { query: derivedFieldConfig.url },
  42. datasourceUid: derivedFieldConfig.datasourceUid,
  43. datasourceName: dsSettings?.name ?? 'Data source not found',
  44. },
  45. });
  46. } else if (derivedFieldConfig.url) {
  47. acc.push({
  48. // We do not know what title to give here so we count on presentation layer to create a title from metadata.
  49. title: derivedFieldConfig.urlDisplayLabel || '',
  50. // This is hardcoded for Jaeger or Zipkin not way right now to specify datasource specific query object
  51. url: derivedFieldConfig.url,
  52. });
  53. }
  54. return acc;
  55. }, [] as DataLink[]);
  56. return {
  57. name: derivedFieldConfigs[0].name,
  58. type: FieldType.string,
  59. config: {
  60. links: dataLinks,
  61. },
  62. // We are adding values later on
  63. values: new ArrayVector<string>([]),
  64. };
  65. }