[Search] add server logs (#72454)

* improve test stability

* logs and scope search function

* uncomment

* fix ts

* ts

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Liza Katz 2020-07-28 13:00:16 +03:00 committed by GitHub
parent 1c791f39da
commit 95668d4baa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 60 additions and 21 deletions

View file

@ -62,11 +62,11 @@ export class DataServerPlugin implements Plugin<DataPluginSetup, DataPluginStart
private readonly logger: Logger;
constructor(initializerContext: PluginInitializerContext<ConfigSchema>) {
this.searchService = new SearchService(initializerContext);
this.logger = initializerContext.logger.get('data');
this.searchService = new SearchService(initializerContext, this.logger);
this.scriptsService = new ScriptsService();
this.kqlTelemetryService = new KqlTelemetryService(initializerContext);
this.autocompleteService = new AutocompleteService(initializerContext);
this.logger = initializerContext.logger.get('data');
}
public setup(

View file

@ -22,6 +22,9 @@ import { pluginInitializerContextConfigMock } from '../../../../../core/server/m
import { esSearchStrategyProvider } from './es_search_strategy';
describe('ES search strategy', () => {
const mockLogger: any = {
info: () => {},
};
const mockApiCaller = jest.fn().mockResolvedValue({
_shards: {
total: 10,
@ -40,14 +43,14 @@ describe('ES search strategy', () => {
});
it('returns a strategy with `search`', async () => {
const esSearch = await esSearchStrategyProvider(mockConfig$);
const esSearch = await esSearchStrategyProvider(mockConfig$, mockLogger);
expect(typeof esSearch.search).toBe('function');
});
it('calls the API caller with the params with defaults', async () => {
const params = { index: 'logstash-*' };
const esSearch = await esSearchStrategyProvider(mockConfig$);
const esSearch = await esSearchStrategyProvider(mockConfig$, mockLogger);
await esSearch.search((mockContext as unknown) as RequestHandlerContext, { params });
@ -63,7 +66,7 @@ describe('ES search strategy', () => {
it('calls the API caller with overridden defaults', async () => {
const params = { index: 'logstash-*', ignoreUnavailable: false, timeout: '1000ms' };
const esSearch = await esSearchStrategyProvider(mockConfig$);
const esSearch = await esSearchStrategyProvider(mockConfig$, mockLogger);
await esSearch.search((mockContext as unknown) as RequestHandlerContext, { params });
@ -77,7 +80,7 @@ describe('ES search strategy', () => {
it('returns total, loaded, and raw response', async () => {
const params = { index: 'logstash-*' };
const esSearch = await esSearchStrategyProvider(mockConfig$);
const esSearch = await esSearchStrategyProvider(mockConfig$, mockLogger);
const response = await esSearch.search((mockContext as unknown) as RequestHandlerContext, {
params,

View file

@ -17,16 +17,18 @@
* under the License.
*/
import { first } from 'rxjs/operators';
import { SharedGlobalConfig } from 'kibana/server';
import { SharedGlobalConfig, Logger } from 'kibana/server';
import { SearchResponse } from 'elasticsearch';
import { Observable } from 'rxjs';
import { ISearchStrategy, getDefaultSearchParams, getTotalLoaded } from '..';
export const esSearchStrategyProvider = (
config$: Observable<SharedGlobalConfig>
config$: Observable<SharedGlobalConfig>,
logger: Logger
): ISearchStrategy => {
return {
search: async (context, request, options) => {
logger.info(`search ${JSON.stringify(request.params)}`);
const config = await config$.pipe(first()).toPromise();
const defaultParams = getDefaultSearchParams(config);

View file

@ -28,7 +28,10 @@ describe('Search service', () => {
let mockCoreSetup: MockedKeys<CoreSetup<object, DataPluginStart>>;
beforeEach(() => {
plugin = new SearchService(coreMock.createPluginInitializerContext({}));
const mockLogger: any = {
info: () => {},
};
plugin = new SearchService(coreMock.createPluginInitializerContext({}), mockLogger);
mockCoreSetup = coreMock.createSetup();
});

View file

@ -22,6 +22,7 @@ import {
PluginInitializerContext,
CoreSetup,
RequestHandlerContext,
Logger,
} from '../../../../core/server';
import { ISearchSetup, ISearchStart, ISearchStrategy } from './types';
import { registerSearchRoute } from './routes';
@ -41,7 +42,10 @@ interface StrategyMap {
export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
private searchStrategies: StrategyMap = {};
constructor(private initializerContext: PluginInitializerContext) {}
constructor(
private initializerContext: PluginInitializerContext,
private readonly logger: Logger
) {}
public setup(
core: CoreSetup<object, DataPluginStart>,
@ -49,7 +53,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
): ISearchSetup {
this.registerSearchStrategy(
ES_SEARCH_STRATEGY,
esSearchStrategyProvider(this.initializerContext.config.legacy.globalConfig$)
esSearchStrategyProvider(this.initializerContext.config.legacy.globalConfig$, this.logger)
);
core.savedObjects.registerType(searchTelemetry);
@ -65,7 +69,11 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
return { registerSearchStrategy: this.registerSearchStrategy, usage };
}
private search(context: RequestHandlerContext, searchRequest: IEsSearchRequest, options: any) {
private search(
context: RequestHandlerContext,
searchRequest: IEsSearchRequest,
options: Record<string, any>
) {
return this.getSearchStrategy(options.strategy || ES_SEARCH_STRATEGY).search(
context,
searchRequest,
@ -76,17 +84,25 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
public start(): ISearchStart {
return {
getSearchStrategy: this.getSearchStrategy,
search: this.search,
search: (
context: RequestHandlerContext,
searchRequest: IEsSearchRequest,
options: Record<string, any>
) => {
return this.search(context, searchRequest, options);
},
};
}
public stop() {}
private registerSearchStrategy = (name: string, strategy: ISearchStrategy) => {
this.logger.info(`Register strategy ${name}`);
this.searchStrategies[name] = strategy;
};
private getSearchStrategy = (name: string): ISearchStrategy => {
this.logger.info(`Get strategy ${name}`);
const strategy = this.searchStrategies[name];
if (!strategy) {
throw new Error(`Search strategy ${name} not found`);

View file

@ -9,6 +9,7 @@ import {
CoreSetup,
CoreStart,
Plugin,
Logger,
} from '../../../../src/core/server';
import { ES_SEARCH_STRATEGY } from '../../../../src/plugins/data/common';
import { PluginSetup as DataPluginSetup } from '../../../../src/plugins/data/server';
@ -19,12 +20,19 @@ interface SetupDependencies {
}
export class EnhancedDataServerPlugin implements Plugin<void, void, SetupDependencies> {
constructor(private initializerContext: PluginInitializerContext) {}
private readonly logger: Logger;
constructor(private initializerContext: PluginInitializerContext) {
this.logger = initializerContext.logger.get('data_enhanced');
}
public setup(core: CoreSetup, deps: SetupDependencies) {
deps.data.search.registerSearchStrategy(
ES_SEARCH_STRATEGY,
enhancedEsSearchStrategyProvider(this.initializerContext.config.legacy.globalConfig$)
enhancedEsSearchStrategyProvider(
this.initializerContext.config.legacy.globalConfig$,
this.logger
)
);
}

View file

@ -31,6 +31,9 @@ const mockRollupResponse = {
describe('ES search strategy', () => {
const mockApiCaller = jest.fn();
const mockLogger: any = {
info: () => {},
};
const mockContext = {
core: { elasticsearch: { legacy: { client: { callAsCurrentUser: mockApiCaller } } } },
};
@ -41,7 +44,7 @@ describe('ES search strategy', () => {
});
it('returns a strategy with `search`', async () => {
const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$);
const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger);
expect(typeof esSearch.search).toBe('function');
});
@ -50,7 +53,7 @@ describe('ES search strategy', () => {
mockApiCaller.mockResolvedValueOnce(mockAsyncResponse);
const params = { index: 'logstash-*', body: { query: {} } };
const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$);
const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger);
await esSearch.search((mockContext as unknown) as RequestHandlerContext, { params });
@ -66,7 +69,7 @@ describe('ES search strategy', () => {
mockApiCaller.mockResolvedValueOnce(mockAsyncResponse);
const params = { index: 'logstash-*', body: { query: {} } };
const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$);
const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger);
await esSearch.search((mockContext as unknown) as RequestHandlerContext, { id: 'foo', params });
@ -82,7 +85,7 @@ describe('ES search strategy', () => {
mockApiCaller.mockResolvedValueOnce(mockAsyncResponse);
const params = { index: 'foo-程', body: {} };
const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$);
const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger);
await esSearch.search((mockContext as unknown) as RequestHandlerContext, { params });
@ -97,7 +100,7 @@ describe('ES search strategy', () => {
mockApiCaller.mockResolvedValueOnce(mockRollupResponse);
const params = { index: 'foo-程', body: {} };
const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$);
const esSearch = await enhancedEsSearchStrategyProvider(mockConfig$, mockLogger);
await esSearch.search((mockContext as unknown) as RequestHandlerContext, {
indexType: 'rollup',

View file

@ -12,6 +12,7 @@ import {
LegacyAPICaller,
SharedGlobalConfig,
RequestHandlerContext,
Logger,
} from '../../../../../src/core/server';
import {
ISearchOptions,
@ -30,13 +31,15 @@ export interface AsyncSearchResponse<T> {
}
export const enhancedEsSearchStrategyProvider = (
config$: Observable<SharedGlobalConfig>
config$: Observable<SharedGlobalConfig>,
logger: Logger
): ISearchStrategy => {
const search = async (
context: RequestHandlerContext,
request: IEnhancedEsSearchRequest,
options?: ISearchOptions
) => {
logger.info(`search ${JSON.stringify(request.params) || request.id}`);
const config = await config$.pipe(first()).toPromise();
const caller = context.core.elasticsearch.legacy.client.callAsCurrentUser;
const defaultParams = getDefaultSearchParams(config);
@ -48,6 +51,7 @@ export const enhancedEsSearchStrategyProvider = (
};
const cancel = async (context: RequestHandlerContext, id: string) => {
logger.info(`cancel ${id}`);
const method = 'DELETE';
const path = encodeURI(`/_async_search/${id}`);
await context.core.elasticsearch.legacy.client.callAsCurrentUser('transport.request', {