最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot實(shí)現(xiàn)日志系統(tǒng)的完整代碼

 更新時(shí)間:2026年01月23日 16:09:03   作者:悟空碼字  
這篇文章主要為大家詳細(xì)介紹了SpringBoot實(shí)現(xiàn)日志系統(tǒng)的相關(guān)方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

一、日志系統(tǒng):程序員的“偵探助手”

如果你的程序突然“掛掉”了,你卻不知道它死前經(jīng)歷了什么——這比看懸疑電影看到一半停電還難受!日志系統(tǒng)就是你的“偵探助手”,它悄咪咪地記錄著程序的一舉一動(dòng),就像:

  • 攝像頭:誰(shuí)在什么時(shí)候訪問(wèn)了哪個(gè)接口
  • 記事本:程序想了什么、做了什么、遇到了什么挫折
  • 告密者:偷偷告訴你“老板,數(shù)據(jù)庫(kù)又連不上了!”
  • 時(shí)間機(jī)器:能讓你穿越回錯(cuò)誤發(fā)生的瞬間

SpringBoot的日志系統(tǒng)就像一個(gè)“智能管家”,你不配置它也能工作,但配置好了它就能變成“超級(jí)管家”!

二、詳細(xì)步驟:打造你的“程序監(jiān)控室”

第1步:創(chuàng)建SpringBoot項(xiàng)目

# 用Spring Initializr創(chuàng)建一個(gè)新項(xiàng)目
# 或者用IDE的Spring Initializr功能
# 記得勾選:
# - Spring Web (因?yàn)槲覀円獙懡涌?
# - Lombok (減少代碼量,程序員要懶一點(diǎn))

第2步:基礎(chǔ)配置 - 給日志系統(tǒng)“定規(guī)矩”

application.yml(或application.properties)中添加:

# application.yml
spring:
  application:
    name: log-system-demo

logging:
  # 日志級(jí)別:TRACE < DEBUG < INFO < WARN < ERROR
  level:
    root: INFO  # 根日志級(jí)別
    com.example.demo: DEBUG  # 我們的包用DEBUG級(jí)別
    org.springframework.web: INFO
    org.hibernate: WARN
    
  # 文件輸出配置(讓日志有個(gè)“家”)
  file:
    name: logs/my-app.log  # 日志文件路徑
    max-size: 10MB  # 單個(gè)文件最大10MB
    max-history: 30  # 保留30天的日志
    
  # 控制臺(tái)輸出美化(讓日志“顏值”更高)
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} - %magenta([%thread]) - %highlight(%-5level) - %cyan(%logger{36}) - %msg%n"
    file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
    
  # 日志分組(給日志“分班”)
  group:
    web: org.springframework.core.codec, org.springframework.http
    sql: org.hibernate.SQL, org.springframework.jdbc

第3步:創(chuàng)建日志工具類

package com.example.demo.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component
@Slf4j  // Lombok的魔法注解,自動(dòng)生成log對(duì)象
public class LogUtil {
    
    /**
     * 記錄方法進(jìn)入(就像進(jìn)門前喊“我進(jìn)來(lái)啦!”)
     */
    public void methodEnter(String methodName, Object... params) {
        log.debug("方法 {} 被調(diào)用,參數(shù): {}", methodName, params);
    }
    
    /**
     * 記錄方法退出(出門說(shuō)“我走啦!”)
     */
    public void methodExit(String methodName, Object result) {
        log.debug("方法 {} 執(zhí)行完成,返回值: {}", methodName, result);
    }
    
    /**
     * 記錄業(yè)務(wù)關(guān)鍵點(diǎn)(重要的事說(shuō)三遍?不,記一遍就行)
     */
    public void businessLog(String template, Object... args) {
        log.info("業(yè)務(wù)日志: " + template, args);
    }
    
    /**
     * 記錄異常(錯(cuò)誤發(fā)生時(shí)大喊“著火啦!”)
     */
    public void error(String message, Throwable e) {
        log.error("發(fā)生異常: {} - 異常詳情: ", message, e);
    }
    
    /**
     * 慢查詢警告(程序說(shuō)“我...有點(diǎn)卡...”)
     */
    public void slowQuery(long costTime, String query) {
        if (costTime > 1000) {  // 超過(guò)1秒
            log.warn("慢查詢警告! 耗時(shí): {}ms, SQL: {}", costTime, query);
        }
    }
}

第4步:創(chuàng)建AOP切面 - 給所有方法“裝上攝像頭”

package com.example.demo.aop;

import com.example.demo.utils.LogUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

@Aspect
@Component
@Slf4j
@RequiredArgsConstructor
public class LogAspect {
    
    private final LogUtil logUtil;
    
    /**
     * 切點(diǎn):所有Controller層的方法
     */
    @Pointcut("execution(* com.example.demo.controller..*.*(..))")
    public void controllerPointcut() {}
    
    /**
     * 切點(diǎn):所有Service層的方法
     */
    @Pointcut("execution(* com.example.demo.service..*.*(..))")
    public void servicePointcut() {}
    
    /**
     * 環(huán)繞通知:Controller層日志
     */
    @Around("controllerPointcut()")
    public Object logController(ProceedingJoinPoint joinPoint) throws Throwable {
        // 獲取請(qǐng)求信息
        ServletRequestAttributes attributes = 
            (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        
        String requestUrl = "Unknown";
        String httpMethod = "Unknown";
        String ip = "Unknown";
        
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            requestUrl = request.getRequestURL().toString();
            httpMethod = request.getMethod();
            ip = request.getRemoteAddr();
        }
        
        String methodName = joinPoint.getSignature().getName();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        Object[] args = joinPoint.getArgs();
        
        // 記錄請(qǐng)求開始
        log.info("\n========== 請(qǐng)求進(jìn)入 ==========");
        log.info("URL: {} {}", httpMethod, requestUrl);
        log.info("IP: {}", ip);
        log.info("類: {}.{}", className, methodName);
        log.info("參數(shù): {}", Arrays.toString(args));
        
        long startTime = System.currentTimeMillis();
        Object result;
        
        try {
            // 執(zhí)行原方法
            result = joinPoint.proceed();
            long costTime = System.currentTimeMillis() - startTime;
            
            // 記錄請(qǐng)求完成
            log.info("請(qǐng)求成功,耗時(shí): {}ms", costTime);
            log.info("返回結(jié)果: {}", result);
            log.info("========== 請(qǐng)求結(jié)束 ==========\n");
            
            return result;
            
        } catch (Exception e) {
            long costTime = System.currentTimeMillis() - startTime;
            
            // 記錄異常
            log.error("請(qǐng)求失敗,耗時(shí): {}ms", costTime);
            log.error("異常信息: {}", e.getMessage());
            log.info("========== 請(qǐng)求異常結(jié)束 ==========\n");
            
            throw e;
        }
    }
    
    /**
     * 環(huán)繞通知:Service層日志
     */
    @Around("servicePointcut()")
    public Object logService(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        
        logUtil.methodEnter(methodName, args);
        long startTime = System.currentTimeMillis();
        
        try {
            Object result = joinPoint.proceed();
            long costTime = System.currentTimeMillis() - startTime;
            
            logUtil.methodExit(methodName, result);
            logUtil.slowQuery(costTime, methodName + " 方法執(zhí)行");
            
            return result;
        } catch (Exception e) {
            logUtil.error("Service方法執(zhí)行失敗: " + methodName, e);
            throw e;
        }
    }
}

第5步:創(chuàng)建Controller和Service - 讓日志系統(tǒng)“有活干”

// UserController.java
package com.example.demo.controller;

import com.example.demo.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/users")
@Slf4j
@RequiredArgsConstructor
public class UserController {
    
    private final UserService userService;
    
    @GetMapping("/{id}")
    public String getUser(@PathVariable Long id) {
        log.info("查詢用戶,ID: {}", id);
        return userService.getUserById(id);
    }
    
    @PostMapping
    public String createUser(@RequestBody String userData) {
        log.info("創(chuàng)建用戶,數(shù)據(jù): {}", userData);
        // 模擬業(yè)務(wù)異常
        if ("bad".equals(userData)) {
            throw new RuntimeException("用戶數(shù)據(jù)不合法!");
        }
        return "用戶創(chuàng)建成功: " + userData;
    }
}

// UserService.java
package com.example.demo.service;

import com.example.demo.utils.LogUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class UserService {
    
    private final LogUtil logUtil;
    
    public String getUserById(Long id) {
        logUtil.businessLog("根據(jù)ID查詢用戶,ID: {}", id);
        
        // 模擬數(shù)據(jù)庫(kù)查詢
        try {
            Thread.sleep(50);  // 模擬耗時(shí)
            if (id == 999) {
                throw new RuntimeException("用戶不存在!");
            }
            return "用戶" + id;
        } catch (InterruptedException e) {
            logUtil.error("查詢用戶時(shí)發(fā)生異常", e);
            return "查詢失敗";
        }
    }
}

第6步:創(chuàng)建全局異常處理 - 給錯(cuò)誤“擦屁股”

package com.example.demo.handler;

import com.example.demo.utils.LogUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@RestControllerAdvice
@Slf4j
@RequiredArgsConstructor
public class GlobalExceptionHandler {
    
    private final LogUtil logUtil;
    
    @ExceptionHandler(Exception.class)
    public Map<String, Object> handleException(HttpServletRequest request, Exception e) {
        // 記錄異常日志
        logUtil.error("全局異常捕獲", e);
        
        // 返回友好錯(cuò)誤信息
        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "服務(wù)器開小差了,請(qǐng)稍后再試!");
        result.put("path", request.getRequestURI());
        result.put("timestamp", System.currentTimeMillis());
        
        // 開發(fā)環(huán)境顯示詳細(xì)錯(cuò)誤
        if (isDevelopment()) {
            result.put("error", e.getMessage());
            result.put("stackTrace", e.getStackTrace());
        }
        
        return result;
    }
    
    private boolean isDevelopment() {
        // 這里可以根據(jù)配置判斷環(huán)境
        return true;  // 假設(shè)是開發(fā)環(huán)境
    }
}

第7步:創(chuàng)建日志查看接口(可選) - 給日志開個(gè)“后門”

package com.example.demo.controller;

import org.springframework.web.bind.annotation.*;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/log")
public class LogController {
    
    @GetMapping("/tail")
    public List<String> getLogTail(@RequestParam(defaultValue = "100") int lines) {
        List<String> result = new ArrayList<>();
        String logFile = "logs/my-app.log";
        
        try (BufferedReader reader = new BufferedReader(new FileReader(logFile))) {
            List<String> allLines = new ArrayList<>();
            String line;
            
            while ((line = reader.readLine()) != null) {
                allLines.add(line);
            }
            
            // 獲取最后N行
            int start = Math.max(0, allLines.size() - lines);
            for (int i = start; i < allLines.size(); i++) {
                result.add(allLines.get(i));
            }
            
        } catch (IOException e) {
            result.add("讀取日志文件失敗: " + e.getMessage());
        }
        
        return result;
    }
}

第8步:配置文件分離(高級(jí)技巧) - 給不同環(huán)境“穿不同衣服”

# application-dev.yml (開發(fā)環(huán)境)
logging:
  level:
    root: DEBUG  # 開發(fā)環(huán)境詳細(xì)日志
  file:
    name: logs/dev-app.log
    
# application-prod.yml (生產(chǎn)環(huán)境)
logging:
  level:
    root: INFO  # 生產(chǎn)環(huán)境精簡(jiǎn)日志
    com.example.demo: WARN  # 自己的包只記錄警告
  file:
    name: /var/log/my-app/app.log  # Linux系統(tǒng)標(biāo)準(zhǔn)日志目錄

三、啟動(dòng)和測(cè)試

1. 啟動(dòng)應(yīng)用

# 設(shè)置激活的環(huán)境
java -jar demo.jar --spring.profiles.active=dev

2. 測(cè)試接口

# 正常請(qǐng)求
curl http://localhost:8080/users/1

# 觸發(fā)異常
curl -X POST http://localhost:8080/users -d "bad"

# 查看日志
curl http://localhost:8080/log/tail?lines=50

3. 觀察控制臺(tái)輸出

你會(huì)看到彩色高亮的日志:

2026-01-21 10:30:25 - [http-nio-8080-exec-1] - INFO  - c.e.demo.controller.UserController - 查詢用戶,ID: 1
2026-01-21 10:30:25 - [http-nio-8080-exec-1] - DEBUG - c.e.demo.aop.LogAspect - 方法 getUserById 被調(diào)用,參數(shù): [1]

四、高級(jí)功能擴(kuò)展

1. 添加日志脫敏(保護(hù)敏感信息)

@Component
public class LogSensitiveFilter {
    public String filterSensitive(String logContent) {
        // 脫敏手機(jī)號(hào)
        logContent = logContent.replaceAll("(1[3-9]\\d{9})", "$1****");
        // 脫敏身份證
        logContent = logContent.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1**********$2");
        // 脫敏郵箱
        logContent = logContent.replaceAll("(\\w{3})(\\w+)(@\\w+\\.\\w+)", "$1****$3");
        return logContent;
    }
}

2. 集成ELK(日志分析全家桶)

# 添加Logstash依賴
dependencies:
  implementation 'net.logstash.logback:logstash-logback-encoder:7.0'

配置logback-spring.xml

<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <destination>localhost:5000</destination>
    <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
        <providers>
            <timestamp/>
            <logLevel/>
            <loggerName/>
            <message/>
            <mdc/>
            <stackTrace/>
        </providers>
    </encoder>
</appender>

3. 自定義Appender(發(fā)送到企業(yè)微信/釘釘)

public class DingTalkAppender extends AppenderBase<ILoggingEvent> {
    @Override
    protected void append(ILoggingEvent event) {
        if (event.getLevel().isGreaterOrEqual(Level.ERROR)) {
            String message = String.format("【系統(tǒng)告警】\n時(shí)間: %s\n級(jí)別: %s\n消息: %s",
                new Date(event.getTimeStamp()),
                event.getLevel(),
                event.getFormattedMessage());
            // 調(diào)用釘釘機(jī)器人API
            sendToDingTalk(message);
        }
    }
}

五、總結(jié):日志系統(tǒng)的“生存法則”

1.日志不是越多越好

就像吃飯不是越多越好一樣,日志也要“適量”:

  • DEBUG級(jí)別:開發(fā)環(huán)境用,生產(chǎn)環(huán)境關(guān)掉
  • INFO級(jí)別:記錄關(guān)鍵業(yè)務(wù)路徑
  • WARN級(jí)別:需要關(guān)注但不緊急的問(wèn)題
  • ERROR級(jí)別:必須立即處理的問(wèn)題

2.日志要“有意義”

糟糕的日志:用戶操作完成 好的日志:用戶[張三]于[2026-01-21 10:30:25]完成了訂單[202601210001]的支付,金額[299.00]元

3.結(jié)構(gòu)化日志是趨勢(shì)

{
  "timestamp": "2026-01-21T10:30:25.123Z",
  "level": "INFO",
  "service": "user-service",
  "traceId": "abc-123-def-456",
  "userId": "user_001",
  "action": "place_order",
  "details": {
    "orderId": "202601210001",
    "amount": 299.00
  }
}

4.性能很重要

  • 使用異步日志:AsyncAppender
  • 避免在日志中拼接大字符串
  • 生產(chǎn)環(huán)境關(guān)掉不必要的日志級(jí)別

5.安全不能忘

  • 敏感信息必須脫敏
  • 日志文件要設(shè)置權(quán)限
  • 生產(chǎn)環(huán)境日志不能包含調(diào)試信息

6.監(jiān)控告警要跟上

  • 錯(cuò)誤日志實(shí)時(shí)告警
  • 慢查詢統(tǒng)計(jì)
  • 接口調(diào)用量監(jiān)控

六、最后

  • 寫日志就像寫日記:不僅要記錄“做了什么”,還要記錄“為什么這么做”
  • 日志是給“未來(lái)的你”看的:想象一下凌晨3點(diǎn)被報(bào)警電話叫醒,清晰的日志能讓你少掉幾根頭發(fā)
  • 日志不是萬(wàn)能的:關(guān)鍵業(yè)務(wù)邏輯該有監(jiān)控還要有監(jiān)控,該有告警還要有告警
  • 定期review日志:就像定期體檢,能發(fā)現(xiàn)潛在問(wèn)題

一個(gè)好的日志系統(tǒng)就像一位可靠的“副駕駛”,在你開車的路上,它不會(huì)打擾你,但會(huì)在你需要的時(shí)候,準(zhǔn)確地告訴你:

  • “前面有坑!”(ERROR)
  • “油不多了”(WARN)
  • “風(fēng)景不錯(cuò)”(INFO)
  • “我在記錄一切”(DEBUG)

去給你的SpringBoot應(yīng)用裝上這個(gè)“智能行車記錄儀”吧!你的程序會(huì)感謝你,你的同事會(huì)感謝你,凌晨三點(diǎn)被叫醒處理問(wèn)題的那個(gè)你,更會(huì)感謝你!

以上就是SpringBoot實(shí)現(xiàn)日志系統(tǒng)的完整代碼的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot日志系統(tǒng)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入淺析jni中的java接口使用

    深入淺析jni中的java接口使用

    這篇文章主要介紹了jni中的java接口使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java 面向?qū)ο蠛头庋b全面梳理總結(jié)

    Java 面向?qū)ο蠛头庋b全面梳理總結(jié)

    面向?qū)ο竽耸荍ava語(yǔ)言的核心,是程序設(shè)計(jì)的思想,在面向?qū)ο蟪淌皆O(shè)計(jì)方法中,封裝(英語(yǔ):Encapsulation)是指一種將抽象性函式接口的實(shí)現(xiàn)細(xì)節(jié)部分包裝、隱藏起來(lái)的方法。封裝可以被認(rèn)為是一個(gè)保護(hù)屏障,防止該類的代碼和數(shù)據(jù)被外部類定義的代碼隨機(jī)訪問(wèn)
    2021-10-10
  • Spring Boot2.X中findOne的使用詳解

    Spring Boot2.X中findOne的使用詳解

    這篇文章主要介紹了Spring Boot2.X中findOne的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot集成Mybatis-plus并實(shí)現(xiàn)自動(dòng)生成相關(guān)文件的示例代碼

    SpringBoot集成Mybatis-plus并實(shí)現(xiàn)自動(dòng)生成相關(guān)文件的示例代碼

    Mybatis-Plus是一個(gè)優(yōu)秀的Mybatis增強(qiáng)工具,目前更新到3.1.1,本文通過(guò)示例代碼給大家介紹SpringBoot集成Mybatis-plus并實(shí)現(xiàn)自動(dòng)生成相關(guān)文件的問(wèn)題,感興趣的朋友跟隨小編一起看看吧
    2021-12-12
  • Java流程控制語(yǔ)句最全匯總(下篇)

    Java流程控制語(yǔ)句最全匯總(下篇)

    這篇文章主要介紹了Java流程控制語(yǔ)句最全匯總(下篇),本文章內(nèi)容詳細(xì),通過(guò)案例可以更好的理解數(shù)組的相關(guān)知識(shí),本模塊分為了三部分,本次為下篇,需要的朋友可以參考下
    2023-01-01
  • Spring?Retry優(yōu)雅地實(shí)現(xiàn)方法重試機(jī)制

    Spring?Retry優(yōu)雅地實(shí)現(xiàn)方法重試機(jī)制

    Spring?Retry?是?Spring?提供的一個(gè)模塊,它可以幫助我們以聲明式的方式為方法添加重試功能,從而提升系統(tǒng)的健壯性和可用性,下面我們就來(lái)看看如何使用Spring?Retry實(shí)現(xiàn)方法重試機(jī)制吧
    2025-06-06
  • 淺談java項(xiàng)目與javaweb項(xiàng)目導(dǎo)入jar包的區(qū)別

    淺談java項(xiàng)目與javaweb項(xiàng)目導(dǎo)入jar包的區(qū)別

    下面小編就為大家分享一篇淺談java項(xiàng)目與javaweb項(xiàng)目導(dǎo)入jar包的區(qū)別,具有很好的參考價(jià)值。希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • 聊聊如何在springboot中添加模版

    聊聊如何在springboot中添加模版

    本文,我們談?wù)勅绾卧?nbsp;spring boot 中添加模版,因?yàn)橛袝r(shí)候我們也是需要后端渲染的嘛,比如公司官網(wǎng),文中有詳細(xì)的代碼示例供我們參考,需要的朋友可以參考下
    2023-08-08
  • java鎖機(jī)制ReentrantLock源碼實(shí)例分析

    java鎖機(jī)制ReentrantLock源碼實(shí)例分析

    這篇文章主要為大家介紹了java鎖機(jī)制ReentrantLock源碼實(shí)例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • springboot2自動(dòng)加載sql文件的實(shí)現(xiàn)

    springboot2自動(dòng)加載sql文件的實(shí)現(xiàn)

    本文主要介紹了springboot2自動(dòng)加載sql文件的實(shí)現(xiàn),通過(guò)配置文件或注解的方式,我們可以輕松地將SQL語(yǔ)句映射到數(shù)據(jù)庫(kù)中,實(shí)現(xiàn)自動(dòng)加載,感興趣的可以了解一下
    2023-11-11

最新評(píng)論

丹棱县| 涿州市| 朝阳县| 齐齐哈尔市| 桃园县| 罗源县| 巨野县| 永新县| 上栗县| 苍南县| 北安市| 聊城市| 鄂伦春自治旗| 通河县| 固安县| 玛纳斯县| 湾仔区| 祁连县| 双城市| 上思县| 阜平县| 苗栗县| 原阳县| 麟游县| 青龙| 铜山县| 夏津县| 红原县| 昔阳县| 普陀区| 金山区| 东山县| 呼伦贝尔市| 温泉县| 宜宾市| 三门峡市| 宜昌市| 河北区| 攀枝花市| 禄丰县| 曲沃县|