mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	chore: show events IP (#9512)
https://linear.app/unleash/issue/2-3392/visualize-event-log-ip-address-on-unleash-enterprise-ui Shows events IP for Unleash Enterprise. 
This commit is contained in:
		
							parent
							
								
									d1d1a740f3
								
							
						
					
					
						commit
						242b0de592
					
				@ -89,6 +89,12 @@ const EventCard = ({ entry }: IEventCardProps) => {
 | 
			
		||||
                <dd>{entry.type}</dd>
 | 
			
		||||
                <StyledDefinitionTerm>Changed by:</StyledDefinitionTerm>
 | 
			
		||||
                <dd title={entry.createdBy}>{entry.createdBy}</dd>
 | 
			
		||||
                {entry.ip && (
 | 
			
		||||
                    <>
 | 
			
		||||
                        <StyledDefinitionTerm>IP:</StyledDefinitionTerm>
 | 
			
		||||
                        <dd title={entry.ip}>{entry.ip}</dd>
 | 
			
		||||
                    </>
 | 
			
		||||
                )}
 | 
			
		||||
                <ConditionallyRender
 | 
			
		||||
                    condition={Boolean(entry.project)}
 | 
			
		||||
                    show={
 | 
			
		||||
 | 
			
		||||
@ -41,6 +41,11 @@ export interface EventSchema {
 | 
			
		||||
     * @minimum 1
 | 
			
		||||
     */
 | 
			
		||||
    id: number;
 | 
			
		||||
    /**
 | 
			
		||||
     * The IP address of the user that created the event. Only available in Enterprise.
 | 
			
		||||
     * @nullable
 | 
			
		||||
     */
 | 
			
		||||
    ip?: string | null;
 | 
			
		||||
    /**
 | 
			
		||||
     * The concise, human-readable name of the event.
 | 
			
		||||
     * @nullable
 | 
			
		||||
 | 
			
		||||
@ -32,12 +32,18 @@ export default class EventService {
 | 
			
		||||
 | 
			
		||||
    private eventBus: EventEmitter;
 | 
			
		||||
 | 
			
		||||
    private isEnterprise: boolean;
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        {
 | 
			
		||||
            eventStore,
 | 
			
		||||
            featureTagStore,
 | 
			
		||||
        }: Pick<IUnleashStores, 'eventStore' | 'featureTagStore'>,
 | 
			
		||||
        { getLogger, eventBus }: Pick<IUnleashConfig, 'getLogger' | 'eventBus'>,
 | 
			
		||||
        {
 | 
			
		||||
            getLogger,
 | 
			
		||||
            eventBus,
 | 
			
		||||
            isEnterprise,
 | 
			
		||||
        }: Pick<IUnleashConfig, 'getLogger' | 'eventBus' | 'isEnterprise'>,
 | 
			
		||||
        privateProjectChecker: IPrivateProjectChecker,
 | 
			
		||||
        accessReadModel: IAccessReadModel,
 | 
			
		||||
    ) {
 | 
			
		||||
@ -46,6 +52,7 @@ export default class EventService {
 | 
			
		||||
        this.privateProjectChecker = privateProjectChecker;
 | 
			
		||||
        this.featureTagStore = featureTagStore;
 | 
			
		||||
        this.eventBus = eventBus;
 | 
			
		||||
        this.isEnterprise = isEnterprise;
 | 
			
		||||
        this.accessReadModel = accessReadModel;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -101,6 +108,9 @@ export default class EventService {
 | 
			
		||||
                query: search.query,
 | 
			
		||||
            },
 | 
			
		||||
            queryParams,
 | 
			
		||||
            {
 | 
			
		||||
                withIp: this.isEnterprise,
 | 
			
		||||
            },
 | 
			
		||||
        );
 | 
			
		||||
        return {
 | 
			
		||||
            events,
 | 
			
		||||
 | 
			
		||||
@ -93,6 +93,7 @@ export interface IEventTable {
 | 
			
		||||
    project?: string;
 | 
			
		||||
    environment?: string;
 | 
			
		||||
    tags: ITag[];
 | 
			
		||||
    ip?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const TABLE = 'events';
 | 
			
		||||
@ -374,15 +375,20 @@ class EventStore implements IEventStore {
 | 
			
		||||
    async searchEvents(
 | 
			
		||||
        params: IEventSearchParams,
 | 
			
		||||
        queryParams: IQueryParam[],
 | 
			
		||||
        options?: { withIp?: boolean },
 | 
			
		||||
    ): Promise<IEvent[]> {
 | 
			
		||||
        const query = this.buildSearchQuery(params, queryParams)
 | 
			
		||||
            .select(EVENT_COLUMNS)
 | 
			
		||||
            .select(options?.withIp ? [...EVENT_COLUMNS, 'ip'] : EVENT_COLUMNS)
 | 
			
		||||
            .orderBy('created_at', 'desc')
 | 
			
		||||
            .limit(Number(params.limit) ?? 100)
 | 
			
		||||
            .offset(Number(params.offset) ?? 0);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            return (await query).map(this.rowToEvent);
 | 
			
		||||
            return (await query).map((row) =>
 | 
			
		||||
                options?.withIp
 | 
			
		||||
                    ? { ...this.rowToEvent(row), ip: row.ip }
 | 
			
		||||
                    : this.rowToEvent(row),
 | 
			
		||||
            );
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -102,6 +102,13 @@ export const eventSchema = {
 | 
			
		||||
            nullable: true,
 | 
			
		||||
            description: 'A markdown-formatted summary of the event.',
 | 
			
		||||
        },
 | 
			
		||||
        ip: {
 | 
			
		||||
            type: 'string',
 | 
			
		||||
            nullable: true,
 | 
			
		||||
            description:
 | 
			
		||||
                'The IP address of the user that created the event. Only available in Enterprise.',
 | 
			
		||||
            example: '192.168.1.1',
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    components: {
 | 
			
		||||
        schemas: {
 | 
			
		||||
 | 
			
		||||
@ -400,6 +400,7 @@ export interface IBaseEvent {
 | 
			
		||||
export interface IEvent extends Omit<IBaseEvent, 'ip'> {
 | 
			
		||||
    id: number;
 | 
			
		||||
    createdAt: Date;
 | 
			
		||||
    ip?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IEnrichedEvent extends IEvent {
 | 
			
		||||
 | 
			
		||||
@ -41,6 +41,7 @@ export interface IEventStore
 | 
			
		||||
    searchEvents(
 | 
			
		||||
        params: IEventSearchParams,
 | 
			
		||||
        queryParams: IQueryParam[],
 | 
			
		||||
        options?: { withIp?: boolean },
 | 
			
		||||
    ): Promise<IEvent[]>;
 | 
			
		||||
    getMaxRevisionId(currentMax?: number): Promise<number>;
 | 
			
		||||
    getRevisionRange(start: number, end: number): Promise<IEvent[]>;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user