Springboot項目使用Logback把日志輸出到控制臺或輸出到文件

這篇文章給大家介紹springboot項目使用日志工具Logback把日志輸出到控制臺拍屑,輸出到文件的具體方法凿跳;介紹了Logback的xml配置文件中各個標(biāo)簽的具體內(nèi)容件豌;列出了常見的配置文件內(nèi)容。

Logback簡介:Logback是一個開源的日志組件控嗜,師出同門,與log4j一樣曾掂,logback也是由Ceki Gülcü開發(fā)的開源日志組件壁顶,可以說是log4j的改進(jìn)版;在現(xiàn)如今的項目中若专,logback的出現(xiàn)次數(shù)越來越多,是目前主流首選的日志記錄工具膊爪。
logback分成三個模塊:logback-core嚎莉,logback- classic,logback-access(這個不常用)萝喘。

1.Logback日志組件各個模塊的功能

  • logback-core:提供了LogBack的核心功能琼懊,是另外兩個組件的基礎(chǔ)。
  • logback-classic:實現(xiàn)了Slf4j的API启妹,所以當(dāng)想配合Slf4j使用時醉旦,需要引入logback-classic。

什么是Slf4j:簡單日志門面(Simple Logging Facade for Java)檬输,不是具體的日志解決方案匈棘,它只服務(wù)于各種各樣的日志系統(tǒng)。在使用SLF4J的時候,不需要在代碼中或配置文件中指定你打算使用那個具體的日志系統(tǒng)鹃愤。

  • logback-access:為了集成Servlet環(huán)境而準(zhǔn)備的完域,可提供HTTP-access的日志接口。

2.Logback日志組件各個模塊的maven依賴

  <!-- logback -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>${logback.version}</version>
    </dependency>

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
    </dependency>

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-access</artifactId>
        <version>${logback.version}</version>
    </dependency>

3.項目啟動時Logback日志配置文件掃描規(guī)則

啟動項目時凹耙,logback會按照如下順序掃描配置文件:

  • 在系統(tǒng)配置文件System Properties中尋找是否有l(wèi)ogback.configurationFile對應(yīng)的value
  • 在classpath下尋找是否有l(wèi)ogback.groovy(即logback支持groovy與xml兩種配置方式)
  • 在classpath下尋找是否有l(wèi)ogback-test.xml
  • 在classpath下尋找是否有l(wèi)ogback.xml

以上任何一項找到了乌妙,就不進(jìn)行后續(xù)掃描,按照對應(yīng)的配置進(jìn)行l(wèi)ogback的初始化虐沥,可從控制臺輸出信息中查看加載的配置文件泽艘。

當(dāng)所有以上四項都找不到的情況下,logback會調(diào)用ch.qos.logback.classic.BasicConfigurator的configure方法匹涮,構(gòu)造一個ConsoleAppender用于向控制臺輸出日志,默認(rèn)日志輸出格式為%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n喜每。

在Springboot項目中可以自定義logback配置文件名及文件位置


image.png

要想讓Springboot項目識別到該logback配置文件雳攘,只需要在Springboot配置文件中定義好配置文件的加載路徑即可如下所示:


image.png

4.Logback具體可實現(xiàn)的功能

  • 自動重新加載配置文件
    當(dāng)配置文件修改了,Logback-classic能自動重新加載配置文件刚照。掃描過程快且安全喧兄,它并不需要另外創(chuàng)建一個掃描線程。
  • 自動去除舊的日志文件
    通過設(shè)置TimeBasedRollingPolicy或者SizeAndTimeBasedFNATP的maxHistory屬性吠冤,你可以控制已經(jīng)產(chǎn)生日志文件的最大數(shù)量。如果設(shè)置maxHistory 12闸昨,那那些log文件超過12個月的都會被自動移除。
  • 堆棧樹帶有包版本
    Logback在打出堆棧樹日志時饵较,會帶上包的數(shù)據(jù)循诉。
  • 自動壓縮已經(jīng)打出來的log
    RollingFileAppender在產(chǎn)生新文件的時候,會自動壓縮已經(jīng)打出來的日志文件茄猫。壓縮是個異步過程,所以甚至對于大的日志文件脆侮,在壓縮過程中應(yīng)用不會受任何影響勇劣。

5.Logback配置文件詳解

  1. 根節(jié)點(diǎn)<configuration>
<!-- 輸出logback內(nèi)部日志信息,每隔30s判斷一下配置文件有沒有更新比默,若更新,則重新加載 -->
<configuration scan="true" scanPeriod="30 seconds" debug="true">
    
<!-- 
    scan: 當(dāng)此屬性設(shè)置為true時篡九,配置文件如果發(fā)生改變醋奠,將會被重新加載,默認(rèn)值為true沛善。
    scanPeriod: 設(shè)置監(jiān)測配置文件是否有修改的時間間隔例证,如果沒有給出時間單位迷捧,默認(rèn)單位是毫秒。當(dāng)scan為true時漠秋,此屬性生效。默認(rèn)的時間間隔為1分鐘捅位。
    debug: 當(dāng)此屬性設(shè)置為true時,將打印出logback內(nèi)部日志信息尿扯,實時查看logback運(yùn)行狀態(tài)焰雕。默認(rèn)值為false。
-->
  1. 設(shè)置變量<property>
<configuration>
    <!-- 定義日志文件的存儲地址 -->
    <property name="LOG_HOME" value="log"/>
       <!--格式化輸出:%d表示日期矩屁,%thread表示線程名,%-5level:級別從左顯示5個字符寬度 %msg:日志消息泊脐,%n是換行符-->
    <property name="LOG_PATTERN" value="%d{yyyyMMdd:HH:mm:ss.SSS} [%thread] %-5level  %msg%n"/>
</configuration>
<!--
name:變量的名稱烁峭,可以隨意起名,但建議名字要簡明直譯耘柱;
value:變量的值棍现;
在配置文件中,我們可以用 ${} 的方式來使用己肮,將變量引入到其他節(jié)點(diǎn)中去。
--> 
  1. <appender>

負(fù)責(zé)寫日志的組件娄柳,有兩個必要屬性name和class

  • 常用的控制臺輸出:ConsoleAppender
<!-- name指定<appender>的名稱
     class指定<appender>的全限定名 -->
<!-- 控制臺輸出 appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <!-- <encoder>表示輸出格式 -->
        <pattern>${LOG_PATTERN}</pattern>
        <!-- 控制臺也要使用UTF-8艘绍,不要使用GBK,否則會中文亂碼 -->
        <charset>utf8</charset>
    </encoder>
</appender>
  • 常用的滾動記錄文件:RollingFileAppender
<!-- INFO日志 appender: 按照每天生成日志文件 -->
<appender name="INFO-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 過濾器挎挖,只記錄 info 級別以上的日志 -->
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>INFO</level>
    </filter>
    <!-- 寫入的日志文件名航夺,可以使相對目錄也可以是絕對目錄,如果上級目錄不存在則自動創(chuàng)建 -->
    <file>${LOG_HOME}/iot-sdk-info.log</file>
    <!-- 如果為true表示日志被追加到文件結(jié)尾阳掐,如果是false表示清空文件 -->
    <append>true</append>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <!-- 日志文件輸出的文件名: 
            %d:可以包含一個Java.text.SimpleDateFormat指定的時間格式
            %i:自增數(shù)字
        -->
        <fileNamePattern>${LOG_HOME}/iot-sdk-info.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
        <!-- 日志文件保存歷史數(shù)量:控制保留的歸檔文件的最大數(shù)量,如果超出數(shù)量就刪除舊文件 -->
        <maxHistory>30</maxHistory>
        <!-- 文件大小超過100MB歸檔 -->
        <maxFileSize>100MB</maxFileSize>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>${LOG_PATTERN}</pattern>
        <charset>utf8</charset>
    </encoder>
</appender>

4.<encoder>

encoder節(jié)點(diǎn)負(fù)責(zé)兩件事情:

  • 把日志信息轉(zhuǎn)換為字節(jié)數(shù)組
  • 把字節(jié)數(shù)組寫到輸出流

以下是一個常用配置:

<!-- 控制臺輸出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- 用來設(shè)置日志的輸入格式蝙茶,使用“%+轉(zhuǎn)換符”的方式蛉拙,如果要輸出”%”則必須使用”\”進(jìn)行轉(zhuǎn)義。-->
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <!-- 格式化輸出:https://logback.qos.ch/manual/layouts.html
             %d 表示日期孕锄,
             %thread 表示線程名,
             %level 日志級別從左顯示5個字符寬度宦芦,
             %t 線程名
             %file:%line 文件名+行號轴脐,
             %m 日志消息,%n是換行符
             %X{traceId}:自定義設(shè)置的參數(shù)恬涧,后面會說碴巾。
        -->
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %t %file:%line %X{traceId} -| %m%n</pattern>
        <charset>utf8</charset>
    </encoder>
</appender>

5.<filter>

配合appender使用,<filter>是<appender>的一個子節(jié)點(diǎn)厦瓢,表示在當(dāng)前給到的日志級別下再進(jìn)行一次過濾

  • Level 級別過濾器
    根據(jù)日志級別進(jìn)行過濾煮仇。如果日志級別等于配置級別,過濾器會根據(jù)onMath和onMismatch接收(ACCEPT)或拒絕(DENY)日志浙垫。
<!-- 控制臺輸出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- 只記錄error級別的日志 -->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>ERROR</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>${LOG_PATTERN}</pattern>
        <charset>utf8</charset>
    </encoder>
</appender>
  • ThresholdFilter: 臨界值過濾器
    將日志級別低于<level>的全部進(jìn)行過濾。當(dāng)日志級別等于或高于臨界值時杉武,過濾器返回NEUTRAL佃声;當(dāng)日志級別低于臨界值時倘要,日志會被拒絕圾亏。
<!-- 控制臺輸出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- 記錄info級別以上的日志 -->
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>INFO</level>
    </filter>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>${LOG_PATTERN}</pattern>
        <charset>utf8</charset>
    </encoder>
</appender>
  1. <logger>與<root>

<logger>用來設(shè)置某一個包或者具體某一個類的日志打印級別、以及指定appender志鹃。
<logger>可以包含零個或者多個<appender-ref>元素,標(biāo)識這個appender將會添加到這個logger曹铃。
<root>也是<logger>元素,但它是根logger秘血,只有一個level屬性评甜,因為它的name就是ROOT

<!-- name:必填灰粮,指定受此logger約束的某一個包或者具體的某一個類忍坷。這個name表示的是LoggerFactory.getLogger(XXX.class),XXX的包路徑柑肴,包路徑越少越是父級
     level:用來設(shè)置打印級別旬薯,五個常用打印級別從低至高依次為TRACE、DEBUG些侍、INFO、WARN岗宣、ERROR淋样,如果未設(shè)置此級別,那么當(dāng)前l(fā)ogger會繼承上級的級別
     additivity:是否向上級logger傳遞打印信息刊咳,默認(rèn)為true -->
<logger name="com.example.iot" level="DEBUG" additivity="false">
    <appender-ref ref="STDOUT"/>
    <appender-ref ref="INFO-APPENDER"/>
    <appender-ref ref="ERROR-APPENDER"/>
</logger>

<!-- 沒有配置<appender-ref>儡司,表示此<logger>不會打印出任何信息 -->
<logger name="com.example.iot.demo1" level="DEBUG" additivity="true" />

<!-- 沒有配置level,即繼承父級的level跷坝,<logger>的父級為<root>,那么level=info -->
<logger name="com.example.iot.demo2" additivity="false" />

<!-- 控制臺輸出日志級別 -->
<root level="INFO">
    <appender-ref ref="STDOUT"/>
</root>

6.Logback日志常用配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds" debug="true">
    <!-- logback的根節(jié)點(diǎn) <configuration>的屬性scan淮韭、scanPeriod贴届、debug
       scan:        當(dāng)此屬性設(shè)置為true時,配置文件如果發(fā)生改變毫蚓,將會被重新加載元潘,默認(rèn)值為true。
       scanPeriod:  設(shè)置監(jiān)測配置文件是否有修改的時間間隔柬批,如果沒有給出時間單位,默認(rèn)單位是毫秒嗅虏。當(dāng)scan為true時上沐,此屬性生效。默認(rèn)的時間間隔為1分鐘龄广。
       debug:       當(dāng)此屬性設(shè)置為true時蕴侧,將打印出logback內(nèi)部日志信息,實時查看logback運(yùn)行狀態(tài)敲才。默認(rèn)值為false择葡。
     -->

    <!-- 定義日志文件的存儲地址 -->
    <property name="LOG_HOME" value="log"/>
    <!-- 格式化輸出:
        %d          表示日期,
        %thread     表示線程名敏储,
        %level      日志級別從左顯示5個字符寬度已添,
        %thread     線程名
        %file:%line 文件名:行號番舆,
        %m          日志消息矾踱,
        %n          換行符疏哗,
        %X{traceId} 自定義設(shè)置的參數(shù)
        %mdc        自定義參數(shù)
    -->
    <property name="LOG_PATTERN"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%5level) -- [%15.15t] %cyan(%-23.23logger{23}) : %m%n"/>


    <!-- appender是configuration的子節(jié)點(diǎn),是負(fù)責(zé)寫日志的組件 -->
    <!-- 控制臺輸出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
            <!-- 控制臺也要使用UTF-8贝搁,不要使用GBK芽偏,否則會中文亂碼 -->
            <charset>utf8</charset>
        </encoder>
    </appender>

    <!-- INFO日志 appender: 按照每天生成日志文件 -->
    <appender name="INFO-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 過濾器,記錄info級別以上的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <!-- 寫入的日志文件名膀哲,可以使相對目錄也可以是絕對目錄被碗,如果上級目錄不存在則自動創(chuàng)建 -->
        <file>${LOG_HOME}/iot-sdk-info.log</file>
        <!-- 如果為true表示日志被追加到文件結(jié)尾,如果是false表示清空文件 -->
        <append>true</append>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 日志文件輸出的文件名: %d可以包含一個Java.text.SimpleDateFormat指定的時間格式 -->
            <fileNamePattern>${LOG_HOME}/iot-sdk-info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 日志文件保存歷史數(shù)量:控制保留的歸檔文件的最大數(shù)量兴喂,如果超出數(shù)量就刪除舊文件 -->
            <maxHistory>30</maxHistory>
            <!-- 文件大小超過100MB歸檔 -->
            <maxFileSize>100MB</maxFileSize>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <!-- 錯誤日志 appender: 按照每天生成日志文件 -->
    <appender name="ERROR-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 過濾器焚志,只記錄error級別的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- 日志名稱 -->
        <file>${LOG_HOME}/iot-sdk-error.log</file>
        <append>true</append>
        <!-- 每天生成一個日志文件酱酬,保存30天的日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 日志文件輸出的文件名:按天回滾 daily -->
            <fileNamePattern>${LOG_HOME}/iot-sdk-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 日志文件保留天數(shù) -->
            <maxHistory>30</maxHistory>
            <!-- 文件大小超過100MB歸檔 -->
            <maxFileSize>100MB</maxFileSize>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <!-- 指定項目中某個包,當(dāng)有日志操作行為時的日志記錄級別
        級別依次為【從高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE
        additivity=false 表示匹配之后佃迄,不再繼續(xù)傳遞給其他的logger
    -->
    <logger name="com.example.iot" level="DEBUG" additivity="false">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="INFO-APPENDER"/>
        <appender-ref ref="ERROR-APPENDER"/>
    </logger>

    <!-- 控制臺輸出日志級別 -->
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

7.Logback高級特性異步輸出日志

之前的日志配置方式是基于同步的贵少,每次日志輸出到文件都會進(jìn)行一次磁盤IO。采用異步寫日志的方式而不讓此次寫日志發(fā)生磁盤IO普碎,阻塞線程從而造成不必要的性能損耗录平。異步輸出日志的方式很簡單缀皱,添加一個基于異步寫日志的appender动猬,并指向原先配置的appender即可。
logback AsyncAppender 目前在logback 1.0.11及以上版本存在

示例:

<!-- 異步輸出 -->
    <appender name="ASYNC-INFO-APPENDER" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丟失日志.默認(rèn)的,如果隊列的80%已滿,則會丟棄TRACT钮莲、DEBUG彼水、INFO級別的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默認(rèn)的隊列的深度,該值會影響性能.默認(rèn)值為256 -->
        <queueSize>256</queueSize>
        <!-- 添加附加的appender,最多只能添加一個 -->
        <appender-ref ref="INFO-APPENDER"/>
    </appender>

    <appender name="ASYNC-ERROR-APPENDER" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丟失日志.默認(rèn)的,如果隊列的80%已滿,則會丟棄TRACT、DEBUG链瓦、INFO級別的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默認(rèn)的隊列的深度,該值會影響性能.默認(rèn)值為256 -->
        <queueSize>256</queueSize>
        <!-- 添加附加的appender,最多只能添加一個 -->
        <appender-ref ref="ERROR-APPENDER"/>
    </appender>

<!-- 設(shè)置開發(fā)環(huán)境日志級別為INFO(采用異步輸出的方式) -->
<!-- springProfile 標(biāo)簽下面會講 -->
<springProfile name="prod">
    <root level="INFO">
        <appender-ref ref="ASYNC-INFO-APPENDER"/>
    </root>
</springProfile>

8.Logback配置文件與Springboot配置文件的配合

1.springProfile標(biāo)簽盯桦,可實現(xiàn)根據(jù)不同的springboot配置文件進(jìn)行不同級別的日志打印

該 <springProfile> 標(biāo)簽允許我們更加靈活配置文件,可選地包含或排除配置部分肥卡。元素中的任何位置均支持輪廓部分事镣。使用該name屬性指定哪個配置文件接受配置》兆粒可以使用逗號分隔列表指定多個配置文件随闪。

<springProfile name="dev">
    <!-- 開發(fā)環(huán)境時激活 -->
</springProfile>

<springProfile name="dev,test">
    <!-- 開發(fā),測試的時候激活-->
</springProfile>

<springProfile name="!prod">
    <!-- 當(dāng) "生產(chǎn)" 環(huán)境時铐伴,該配置不激活-->
</springProfile>
  • 案例
<!-- 開發(fā)環(huán)境日志級別為DEBUG -->
<springProfile name="dev">
    <root level="DEBUG">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="INFO-APPENDER"/>
    </root>
</springProfile>

<!-- 測試環(huán)境日志級別為INFO -->
<springProfile name="test">
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="INFO-APPENDER"/>
    </root>

<!-- 生產(chǎn)環(huán)境日志級別為INFO -->
<springProfile name="prod">
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="INFO-APPENDER"/>
    </root>
</springProfile>

2.springProperty

  • 該 <springProperty> 標(biāo)簽允許我們從Spring中顯示屬性当宴,Environment 以便在Logback中使用。如果你想將 application.properties在回讀配置中訪問文件中的值玲献,這將非常有用。

  • 標(biāo)簽的工作方式與Logback的標(biāo)準(zhǔn) <property> 標(biāo)簽類似捌年,但不是直接value 指定source屬性(從Environment)指定。scope 如果需要將屬性存儲在local范圍之外的其他位置眠砾,則可以使用該屬性托酸。如果您需要一個后備值,以防該屬性未設(shè)置,則Environment可以使用該defaultValue屬性吻育。

<!-- 從Spring環(huán)境變量中獲取值, source屬性是springboot配置文件中的key -->
<springProperty scope="context" name="LOGBACK_NAME" source="springboot.application.name" defaultValue="appName"/>

<!-- 應(yīng)用 通過${name}引入-->
<appender name="EXAMPLE" class="ch.qos.logback.more.appenders.EXAMPLEAppender">
    <remoteHost>${LOGBACK_NAME}</remoteHost>
</appender>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末摊趾,一起剝皮案震驚了整個濱河市游两,隨后出現(xiàn)的幾起案子贱案,更是在濱河造成了極大的恐慌,老刑警劉巖宝踪,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瘩燥,死亡現(xiàn)場離奇詭異,居然都是意外死亡厉膀,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門凳兵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來企软,“玉大人,你說我怎么就攤上這事聚蝶。” “怎么了碘勉?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵验靡,是天一觀的道長。 經(jīng)常有香客問我胜嗓,道長,這世上最難降的妖魔是什么怔锌? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任变过,我火速辦了婚禮,結(jié)果婚禮上岛杀,老公的妹妹穿的比我還像新娘崭孤。我一直安慰自己,他們只是感情好土浸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布彭羹。 她就那樣靜靜地躺著,像睡著了一般还最。 火紅的嫁衣襯著肌膚如雪毡惜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天扶叉,我揣著相機(jī)與錄音,去河邊找鬼枣氧。 笑死,一個胖子當(dāng)著我的面吹牛张弛,可吹牛的內(nèi)容都是我干的酪劫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼刻剥,長吁一口氣:“原來是場噩夢啊……” “哼滩字!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起踢械,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤内列,失蹤者是張志新(化名)和其女友劉穎背率,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寝姿,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饵筑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了架专。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玄帕。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖委刘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情锡移,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布拉庵,位于F島的核電站套蒂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏烁挟。R本人自食惡果不足惜骨坑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望且警。 院中可真熱鬧礁遣,春花似錦、人聲如沸祟霍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽崭添。三九已至,卻和暖如春棘伴,著一層夾襖步出監(jiān)牢的瞬間徙邻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工淳地, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人颇象。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像扰魂,于是被迫代替她去往敵國和親蕴茴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容