1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-23 00:22:19 +01:00

fix: log diff (#5072)

Add a deep diff function to investigate diff in logs
This commit is contained in:
Fredrik Strand Oseberg 2023-10-18 09:25:25 +02:00 committed by GitHub
parent 75b131162e
commit 3ac8ab898a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 143 additions and 5 deletions

View File

@ -151,8 +151,8 @@
"devDependencies": { "devDependencies": {
"@apidevtools/swagger-parser": "10.1.0", "@apidevtools/swagger-parser": "10.1.0",
"@babel/core": "7.23.0", "@babel/core": "7.23.0",
"@swc/core": "1.3.92",
"@biomejs/biome": "1.2.2", "@biomejs/biome": "1.2.2",
"@swc/core": "1.3.92",
"@swc/jest": "0.2.29", "@swc/jest": "0.2.29",
"@types/bcryptjs": "2.4.4", "@types/bcryptjs": "2.4.4",
"@types/cors": "2.8.14", "@types/cors": "2.8.14",

View File

@ -0,0 +1,66 @@
interface Difference {
index: (string | number)[];
reason: string;
valueA: any;
valueB: any;
}
export function deepDiff(arr1: any[], arr2: any[]): Difference[] | null {
const diff: Difference[] = [];
function compare(a: any, b: any, parentIndex: (string | number)[]): void {
if (Array.isArray(a) && Array.isArray(b)) {
if (a.length !== b.length) {
diff.push({
index: parentIndex,
reason: 'Different lengths',
valueA: a,
valueB: b,
});
} else {
for (let i = 0; i < a.length; i++) {
compare(a[i], b[i], parentIndex.concat(i));
}
}
} else if (
typeof a === 'object' &&
a !== null &&
typeof b === 'object' &&
b !== null
) {
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (!arraysEqual(keysA, keysB)) {
diff.push({
index: parentIndex,
reason: 'Different keys',
valueA: a,
valueB: b,
});
} else {
for (const key of keysA) {
compare(a[key], b[key], parentIndex.concat(key));
}
}
} else if (a !== b) {
diff.push({
index: parentIndex,
reason: 'Different values',
valueA: a,
valueB: b,
});
}
}
function arraysEqual(a: any[], b: any[]): boolean {
return (
a.length === b.length &&
a.sort().every((val, index) => val === b.sort()[index])
);
}
compare(arr1, arr2, []);
return diff.length > 0 ? diff : null;
}

View File

@ -103,6 +103,7 @@ import { IDependentFeaturesReadModel } from '../dependent-features/dependent-fea
import EventService from '../../services/event-service'; import EventService from '../../services/event-service';
import { DependentFeaturesService } from '../dependent-features/dependent-features-service'; import { DependentFeaturesService } from '../dependent-features/dependent-features-service';
import isEqual from 'lodash.isequal'; import isEqual from 'lodash.isequal';
import { deepDiff } from './deep-diff';
interface IFeatureContext { interface IFeatureContext {
featureName: string; featureName: string;
@ -1067,12 +1068,17 @@ class FeatureToggleService {
); );
if (!equal) { if (!equal) {
const difference = deepDiff(
featuresFromClientStore,
featuresFromFeatureToggleStore,
);
this.logger.warn( this.logger.warn(
'features from client-feature-toggle-store is not equal to features from feature-toggle-store', 'getPlaygroundFeatures: features from client-feature-toggle-store is not equal to features from feature-toggle-store',
difference,
); );
} }
const features = this.flagResolver.isEnabled('useLastSeenRefactor') const features = this.flagResolver.isEnabled('separateAdminClientApi')
? featuresFromFeatureToggleStore ? featuresFromFeatureToggleStore
: featuresFromClientStore; : featuresFromClientStore;
@ -1113,12 +1119,17 @@ class FeatureToggleService {
); );
if (!equal) { if (!equal) {
const difference = deepDiff(
featuresFromClientStore,
featuresFromFeatureToggleStore,
);
this.logger.warn( this.logger.warn(
'features from client-feature-toggle-store is not equal to features from feature-toggle-store diff', 'getFeatureToggles: features from client-feature-toggle-store is not equal to features from feature-toggle-store diff',
difference,
); );
} }
const features = this.flagResolver.isEnabled('useLastSeenRefactor') const features = this.flagResolver.isEnabled('separateAdminClientApi')
? featuresFromFeatureToggleStore ? featuresFromFeatureToggleStore
: featuresFromClientStore; : featuresFromClientStore;

View File

@ -0,0 +1,61 @@
import { deepDiff } from '../deep-diff'; // Import the deepDiff function
describe('deepDiff', () => {
it('should return null for equal arrays', () => {
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
expect(deepDiff(arr1, arr2)).toBe(null);
});
it('should find differences in arrays with different lengths', () => {
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3, 4];
expect(deepDiff(arr1, arr2)).toEqual([
{
index: [],
reason: 'Different lengths',
valueA: arr1,
valueB: arr2,
},
]);
});
it('should find differences in arrays with different values', () => {
const arr1 = [1, 2, 3];
const arr2 = [1, 4, 3];
expect(deepDiff(arr1, arr2)).toEqual([
{
index: [1],
reason: 'Different values',
valueA: 2,
valueB: 4,
},
]);
});
it('should find differences in arrays with different keys in objects', () => {
const arr1 = [{ a: 1 }, { b: 2 }];
const arr2 = [{ a: 1 }, { c: 2 }];
expect(deepDiff(arr1, arr2)).toEqual([
{
index: [1],
reason: 'Different keys',
valueA: { b: 2 },
valueB: { c: 2 },
},
]);
});
it('should handle nested differences in objects', () => {
const arr1 = [{ a: { b: 1 } }, { c: { d: 2 } }];
const arr2 = [{ a: { b: 1 } }, { c: { d: 3 } }];
expect(deepDiff(arr1, arr2)).toEqual([
{
index: [1, 'c', 'd'],
reason: 'Different values',
valueA: 2,
valueB: 3,
},
]);
});
});