# fineely-log
**Repository Path**: kepler_16b/fineely-log
## Basic Information
- **Project Name**: fineely-log
- **Description**: Record Request Interface Log
- **Primary Language**: Java
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2023-03-31
- **Last Updated**: 2025-01-17
## Categories & Tags
**Categories**: Uncategorized
**Tags**: log, Kafka, feign, Java
## README
# [Fineely Log](http://www.fineely.com/)
The rest interface log collection based on spring aop implementation supports kakfa and openFeign
[](https://central.sonatype.com/artifact/com.fineely/fineely-log/1.0.2)
[](https://blog.csdn.net/leichengjun_510/article/details/129882941)

[](https://github.com/Big-billed-shark/fineely-log/blob/main/LICENSE)
[](https://github.com/Big-billed-shark/fineely-log)
[](https://gitee.com/kepler_16b/fineely-log)
## Pull Requests on Github
By sending a pull request, you grant KeplerLei sufficient permissions to use and publish the work submitted under the KeplerLei license.
## Getting Started
`fineely-log` is available at the Central `Maven` Repository. Maven users add this to your `POM`.
```xml
com.fineely
fineely-log
1.0.3
com.fineely
fineely-log-common
1.0.3
```
Gradle users add this to your `build.gradle`.
```groovy
implementation 'com.fineely:fineely-log:1.0.3'
implementation 'com.fineely:fineely-log-common:1.0.3'
```
## Usage
Basic usage of the `fineely-log` :
```java
package com.example;
import com.fineelyframework.log.annotation.FineelyLog;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/example")
public class Example {
@GetMapping("/hello")
@FineelyLog(method = RequestMethod.GET, module = "example", url = "/example/hello")
public String hello(String name) {
return "Hello: " + name;
}
@GetMapping("/name")
@FineelyLog(method = RequestMethod.GET, module = "example", desc = "${name}")
public String name(String name) {
return name;
}
@PostMapping("/test")
@FineelyLog(method = RequestMethod.POST, module = "example", desc = "${myExample.xx}, Hello ${one}")
public String test(@RequestBody MyExample myExample, @FineelyParam ParamMap paramMap) {
paramMap.put("one", "World");
return "Hello";
}
}
```
In FineelyLog, annotations have a high-level description configuration
```java
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FineelyLog {
/**
* Request Method
*/
RequestMethod[] method() default {};
/**
* Module
*/
String module() default "";
/**
* Description
* Parameter Name ${name} or ${class.name}
* Common parameters are as follows:
*
* Method returns a result: ${result.**}
* Method name: ${methodName}
* Method execution start time: ${startTime}
* Method execution end time: ${endTime}
* Courtship parameter: ${request.**}
* Array matching: ${result.data[0].name}
*/
String desc() default "";
/**
* Request Address
*/
String url() default "";
}
```
And an `queue` example `application.yml` configuration file:
```yaml
fineely:
log:
storage-mode: queue
```
Processing method of the `queue` :
```java
package com.example;
/**
* fineely.log.storageMode = queue
*/
@Slf4j
@Component
public class LogQueueTask {
@Scheduled(fixedRate = 5000)
public void monitorQueueLog(){
LinkedTransferQueue oplogQueue = QueueOperator.INSTANCE.getOplogQueue();
if (!oplogQueue.isEmpty()) {
// do something
List oplogs = new ArrayList<>();
oplogQueue.drainTo(oplogs);
for (MethodLogEntity oplog : oplogs) {
log.info("::::::: logļ¼[{}]", oplog.toString());
}
} else {
log.info("::::::: No log temporarily");
}
}
}
```
And an `feign` example `application.yml` configuration file:
```yaml
fineely:
log:
storage-mode: feign
# Choose between the name and url
# Without eureka, Please use path
feign:
# Application Name registered in eureka
name: example
url: http://localhost:8895
path: /test
# If you need eureka, you can add configurations, set fineely.log.feign.name = target spring.application.name
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1112/eureka/
instance:
prefer-ip-address: true
```
Processing method of the `feign` :
```java
public class LogEntity {
private String[] method;
private String methodName;
private String module;
private String url;
private String desc;
private LocalDateTime startTime;
private LocalDateTime endTime;
private double timeConsuming;
private String allParams;
private String result;
private String ipAddress;
private String exceptionInfo;
private String operator;
private LocalDateTime createTime;
}
@RestController
@RequestMapping("/test")
public class TestController {
/**
* feign mode mapping url is `save`
*/
@PostMapping("save")
public boolean saveLog(@RequestBody LogEntity logEntity) {
System.out.println(myEntity.toString());
// do something
return true;
}
}
```
And an `kafka` example `application.yml` configuration file:
```yaml
fineely:
log:
storage-mode: kafka
kafka:
kafka-brokers: 192.168.3.190:9092
topic: test-server
group-id: e27121ee40c6c6f45f91ab52101b1122
```
Processing method of the `kafka` :
```java
@Configuration
public class KafkaConfig {
@Value("${kafka_brokers}")
private String KAFKA_BROKERS;
@Bean
@ConditionalOnMissingBean(
name = {"messageReceiveListener"}
)
public KafkaListenerContainerFactory> messageReceiveListener() {
ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory();
factory.setConsumerFactory(new DefaultKafkaConsumerFactory(this.consumerConfigs()));
factory.setBatchListener(true);
factory.getContainerProperties().setPollTimeout(1500L);
factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
factory.setConcurrency(4);
return factory;
}
private Map consumerConfigs() {
Map configs = new HashMap<>();
configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, this.KAFKA_BROKERS);
// Other configurations ...
return configs;
}
}
/**
* Kafka listener, listening for log notifications
*/
@Slf4j
@Component
public class KafkaMessageHandler {
@KafkaListener(
containerFactory = "messageReceiveListener",
topics = {"${topic}"},
groupId = "${group-id}"
)
public void consumerCommonMessageNotify(List> records, Acknowledgment ack) {
try {
records.forEach(content -> {
log.info("=====:::::: Start processing message=====");
// do something
String message = content.value().toString();
log.info(String.format(":::::: Receive message content => %s", message));
log.info("=====:::::: Processing Message End=====");
});
} catch (Exception e) {
log.error(":::::: Message processing error => ", e);
} finally {
ack.acknowledge();
}
}
}
```
And an `dubbo` example `application.yml` configuration file:
```yaml
dubbo:
application:
# Application Name
name: example-dubbo
registry:
address: zookeeper://127.0.0.1:2181
fineely:
log:
storage-mode: dubbo
```
`dubbo[provider]` example `application.yml` configuration file:
```yaml
dubbo:
application:
name: dubbo-example-provider-application
protocol:
name: tri
port: -1
registry:
address: zookeeper://127.0.0.1:2181
```
Gradle users add this to your `build.gradle` on `provider`.
```groovy
implementation 'com.fineely:fineely-log-common:1.0.3'
```
Processing method of the `dubbo` :
```java
@DubboService
public class FeignLogDaoImpl implements FeignLogDao {
@Override
public boolean saveLog(MethodLogEntity request) {
System.out.println(request.toString());
return true;
}
}
```
## Senior
Custom Implementation Storage
```java
import com.fineelyframework.log.entity.MethodLogEntity;
/**
* CustomLogDaoImpl
* Implement the MethodLogDao interface
* Yml does not need to add configuration
*/
@Component
public class CustomLogDaoImpl implements MethodLogDao {
@Override
public boolean saveLog(MethodLogEntity methodLogEntity) {
// do something
return true;
}
}
```
## Issue Tracking
Issues, bugs, and feature requests should be submitted to [the issue tracker](https://github.com/Big-billed-shark/fineely-log/issues).
Pull requests on GitHub are welcome, but please open a ticket in the issue tracker first, and mention the issue in the pull request.